YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif
static Field *is_vcol_expr(Vcol_subst_context *ctx, const Item *item); static void subst_vcol_if_compatible(Vcol_subst_context *ctx,
Item_bool_func *cond,
Item **vcol_expr_ref,
Field *vcol_field);
static bool collect_indexed_vcols_for_table(TABLE *table, List<Field> *vcol_fields)
{ // TODO: Make use of iterator to loop through keys_in_use_for_query, instead. for (uint i=0; i < table->s->keys; i++)
{ // note: we could also support histograms here if (!table->keys_in_use_for_query.is_set(i)) continue;
KEY *key= &table->key_info[i]; for (uint kp=0; kp < key->user_defined_key_parts; kp++)
{
Field *field= key->key_part[kp].field; if (field->vcol_info && vcol_fields->push_back(field)) returnTRUE; // Out of memory
}
} returnFALSE; // Ok
}
static bool collect_indexed_vcols_for_join(JOIN *join, List<Field> *vcol_fields)
{
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
TABLE_LIST *tl; while ((tl= ti++))
{ if (!tl->table) // non-merged semi-join or something like that continue; if (collect_indexed_vcols_for_table(tl->table, vcol_fields)) returnTRUE; // Out of memory
} returnFALSE; // Ok
}
/* Substitute virtual columns in an Item tree */ staticvoid subst_vcols_in_item(Vcol_subst_context *ctx, Item *item, constchar *location)
{
uchar *yes= (uchar*) 1;
ctx->subst_count= 0;
bool substitute_indexed_vcols_for_join(JOIN *join)
{
Vcol_subst_context ctx(join->thd); if (collect_indexed_vcols_for_join(join, &ctx.vcol_fields)) returntrue; // Out of memory
if (!ctx.vcol_fields.elements) returnfalse; // Ok, nothing to do
if (join->conds)
subst_vcols_in_item(&ctx, join->conds, "WHERE"); if (join->join_list)
subst_vcols_in_join_list(&ctx, join->join_list);
ctx.subst_count= 0; if (join->order)
subst_vcols_in_order(&ctx, join->order, join, false); /* DonotdosubstitutionforWITHROLLUPasthatbreakssomeofitsdata structures.
*/ if (join->group_list && join->rollup.state == st_rollup::STATE_NONE)
subst_vcols_in_order(&ctx, join->group_list, join, true); if (ctx.subst_count)
{
count_field_types(join->select_lex, &join->tmp_table_param,
join->all_fields, 0);
join->select_lex->update_used_tables();
}
if (join->thd->is_error()) returntrue; // Out of memory returnfalse; // Ok
}
bool substitute_indexed_vcols_for_table(TABLE *table, Item *item,
ORDER *order, SELECT_LEX *select_lex)
{
Vcol_subst_context ctx(table->in_use); if (collect_indexed_vcols_for_table(table, &ctx.vcol_fields)) returntrue; // Out of memory
if (!ctx.vcol_fields.elements) returnfalse; // Ok, nothing to do
if (item)
subst_vcols_in_item(&ctx, item, "WHERE");
ctx.subst_count= 0; /* used in subst_vcol_in_order */ if (order)
subst_vcols_in_order(&ctx, order, select_lex->join, false);
if (table->in_use->is_error()) returntrue; // Out of memory
constchar *fail_cause= NULL; if (cond) /* WHERE substitution (MDEV-39525) */
{ if (vcol_expr->type_handler_for_comparison() !=
vcol_field->type_handler_for_comparison() ||
(vcol_expr->maybe_null() && !vcol_field->maybe_null()))
fail_cause="type mismatch"; else
{
CHARSET_INFO *cs= cond ? cond->compare_collation() : NULL; if (vcol_expr->collation.collation != vcol_field->charset() &&
cs != vcol_field->charset())
fail_cause= "collation mismatch";
}
} else/* ORDER/GROUP BY substitution */
{ if (!vcol_field->type_handler()->is_supertype(
vcol_field->type_std_attributes(),
vcol_field->type_extra_attributes(),
vcol_expr->type_handler(),
*vcol_expr /*Type_std_attributes*/,
vcol_expr->type_extra_attributes()))
fail_cause="failed supertype check"; elseif (vcol_expr->maybe_null() && !vcol_field->maybe_null())
{ /* NOT NULL is not allowed for vcol definition */
DBUG_ASSERT(0);
fail_cause= "nullability mismatch";
}
}
if (fail_cause)
{ if (thd->give_notes_for_unusable_keys())
print_vcol_subst_warning(thd, vcol_field, vcol_expr, fail_cause); return;
}
Item_field *itf= new (thd->mem_root) Item_field(thd, vcol_field); if (!itf) return; // Out of memory, caller will know from thd->is_error()
vcol_expr->walk(&Item::get_context_for_vcol_processor, &itf->context, 0);
bitmap_set_bit(vcol_field->table->read_set, vcol_field->field_index);
DBUG_ASSERT(itf->fixed());
thd->change_item_tree(vcol_expr_ref, itf);
ctx->subst_count++; return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.