Loading sql/item.cc +122 −131 Original line number Diff line number Diff line Loading @@ -3513,6 +3513,9 @@ Item_ref::Item_ref(Item **item, const char *table_name_par, Item_field::fix_fields, here we first search the SELECT and GROUP BY clauses, and then we search the FROM clause. POSTCONDITION Item_ref::ref is 0 or points to a valid item RETURN TRUE if error FALSE on success Loading @@ -3534,6 +3537,19 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (ref == not_found_item) /* This reference was not resolved. */ { TABLE_LIST *table_list; Field *from_field; SELECT_LEX *last; ref= 0; if (!outer_sel || (current_sel->master_unit()->first_select()->linkage == DERIVED_TABLE_TYPE)) { /* The current reference cannot be resolved in this query. */ my_error(ER_BAD_FIELD_ERROR,MYF(0), this->full_name(), current_thd->where); return TRUE; } /* If there is an outer select, and it is not a derived table (which do not support the use of outer fields for now), try to resolve this Loading @@ -3543,13 +3559,10 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) subselects may contain columns with the same names. The subselects are searched starting from the innermost. */ if (outer_sel && (current_sel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)) { TABLE_LIST *table_list; Field *from_field= (Field*) not_found_field; SELECT_LEX *last= 0; from_field= (Field*) not_found_field; last= 0; /* The following loop will always be excuted at least once */ for ( ; outer_sel ; outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) { Loading @@ -3568,16 +3581,24 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) prev_subselect_item->const_item_cache&= (*ref)->const_item(); break; } /* Set ref to 0 to ensure that we get an error in case we replaced this item with another item and still use this item in some other place of the parse tree. */ ref= 0; } /* Search in the tables of the FROM clause of the outer select. */ table_list= outer_sel->get_table_list(); if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { /* It is a primary INSERT st_select_lex => do not resolve against the first table. It is a primary INSERT st_select_lex => do not resolve against the first table. */ table_list= table_list->next_local; } place= prev_subselect_item->parsing_place; /* Loading @@ -3599,18 +3620,13 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) field expression to 'reference', i.e. it substitute that expression instead of this Item_ref */ if ((from_field= find_field_in_tables(thd, this, table_list, from_field= find_field_in_tables(thd, this, table_list, reference, IGNORE_EXCEPT_NON_UNIQUE, TRUE)) != not_found_field) { if (from_field != view_ref_found) { prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; } else TRUE); if (! from_field) return TRUE; if (from_field == view_ref_found) { Item::Type type= (*reference)->type(); prev_subselect_item->used_tables_cache|= Loading @@ -3628,9 +3644,14 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) */ return FALSE; } if (from_field != not_found_field) { prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; break; } } DBUG_ASSERT(from_field == not_found_field); /* Reference is not found => depend on outer (or just error). */ prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; Loading @@ -3641,25 +3662,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) break; /* Do not consider derived tables. */ } DBUG_ASSERT(ref != 0); if (!from_field) return TRUE; if (ref == not_found_item && from_field == not_found_field) { my_error(ER_BAD_FIELD_ERROR, MYF(0), this->full_name(), current_thd->where); ref= 0; // Safety return TRUE; } DBUG_ASSERT(from_field != 0 && from_field != view_ref_found); if (from_field != not_found_field) { /* Set ref to 0 as we are replacing this item with the found item and this will ensure we get an error if this item would be used elsewhere */ ref= 0; // Safety if (from_field != view_ref_found) { Item_field* fld; if (!(fld= new Item_field(from_field))) Loading @@ -3668,34 +3672,20 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) mark_as_dependent(thd, last, thd->lex->current_select, this, fld); return FALSE; } /* We can leave expression substituted from view for next PS/SP re-execution (i.e. do not register this substitution for reverting on cleanup() (register_item_tree_changing())), because this subtree will be fix_field'ed during setup_tables()->setup_ancestor() (i.e. before all other expressions of query, and references on tables which do not present in query will not make problems. Also we suppose that view can't be changed during PS/SP life. */ } else { /* Should be checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); mark_as_dependent(thd, last, current_sel, this, this); } } else if (ref == 0) { /* The current reference cannot be resolved in this query. */ /* The item was not a table field and not a reference */ my_error(ER_BAD_FIELD_ERROR, MYF(0), this->full_name(), current_thd->where); return TRUE; } /* Should be checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); mark_as_dependent(thd, last, current_sel, this, this); } } DBUG_ASSERT(*ref); /* Check if this is an incorrect reference in a group function or forward reference. Do not issue an error if this is an unnamed reference inside an Loading @@ -3716,11 +3706,12 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) set_properties(); if (ref && (*ref)->check_cols(1)) return 1; return 0; if ((*ref)->check_cols(1)) return TRUE; return FALSE; } void Item_ref::set_properties() { max_length= (*ref)->max_length; Loading Loading
sql/item.cc +122 −131 Original line number Diff line number Diff line Loading @@ -3513,6 +3513,9 @@ Item_ref::Item_ref(Item **item, const char *table_name_par, Item_field::fix_fields, here we first search the SELECT and GROUP BY clauses, and then we search the FROM clause. POSTCONDITION Item_ref::ref is 0 or points to a valid item RETURN TRUE if error FALSE on success Loading @@ -3534,6 +3537,19 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (ref == not_found_item) /* This reference was not resolved. */ { TABLE_LIST *table_list; Field *from_field; SELECT_LEX *last; ref= 0; if (!outer_sel || (current_sel->master_unit()->first_select()->linkage == DERIVED_TABLE_TYPE)) { /* The current reference cannot be resolved in this query. */ my_error(ER_BAD_FIELD_ERROR,MYF(0), this->full_name(), current_thd->where); return TRUE; } /* If there is an outer select, and it is not a derived table (which do not support the use of outer fields for now), try to resolve this Loading @@ -3543,13 +3559,10 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) subselects may contain columns with the same names. The subselects are searched starting from the innermost. */ if (outer_sel && (current_sel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)) { TABLE_LIST *table_list; Field *from_field= (Field*) not_found_field; SELECT_LEX *last= 0; from_field= (Field*) not_found_field; last= 0; /* The following loop will always be excuted at least once */ for ( ; outer_sel ; outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) { Loading @@ -3568,16 +3581,24 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) prev_subselect_item->const_item_cache&= (*ref)->const_item(); break; } /* Set ref to 0 to ensure that we get an error in case we replaced this item with another item and still use this item in some other place of the parse tree. */ ref= 0; } /* Search in the tables of the FROM clause of the outer select. */ table_list= outer_sel->get_table_list(); if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { /* It is a primary INSERT st_select_lex => do not resolve against the first table. It is a primary INSERT st_select_lex => do not resolve against the first table. */ table_list= table_list->next_local; } place= prev_subselect_item->parsing_place; /* Loading @@ -3599,18 +3620,13 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) field expression to 'reference', i.e. it substitute that expression instead of this Item_ref */ if ((from_field= find_field_in_tables(thd, this, table_list, from_field= find_field_in_tables(thd, this, table_list, reference, IGNORE_EXCEPT_NON_UNIQUE, TRUE)) != not_found_field) { if (from_field != view_ref_found) { prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; } else TRUE); if (! from_field) return TRUE; if (from_field == view_ref_found) { Item::Type type= (*reference)->type(); prev_subselect_item->used_tables_cache|= Loading @@ -3628,9 +3644,14 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) */ return FALSE; } if (from_field != not_found_field) { prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; break; } } DBUG_ASSERT(from_field == not_found_field); /* Reference is not found => depend on outer (or just error). */ prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; Loading @@ -3641,25 +3662,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) break; /* Do not consider derived tables. */ } DBUG_ASSERT(ref != 0); if (!from_field) return TRUE; if (ref == not_found_item && from_field == not_found_field) { my_error(ER_BAD_FIELD_ERROR, MYF(0), this->full_name(), current_thd->where); ref= 0; // Safety return TRUE; } DBUG_ASSERT(from_field != 0 && from_field != view_ref_found); if (from_field != not_found_field) { /* Set ref to 0 as we are replacing this item with the found item and this will ensure we get an error if this item would be used elsewhere */ ref= 0; // Safety if (from_field != view_ref_found) { Item_field* fld; if (!(fld= new Item_field(from_field))) Loading @@ -3668,34 +3672,20 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) mark_as_dependent(thd, last, thd->lex->current_select, this, fld); return FALSE; } /* We can leave expression substituted from view for next PS/SP re-execution (i.e. do not register this substitution for reverting on cleanup() (register_item_tree_changing())), because this subtree will be fix_field'ed during setup_tables()->setup_ancestor() (i.e. before all other expressions of query, and references on tables which do not present in query will not make problems. Also we suppose that view can't be changed during PS/SP life. */ } else { /* Should be checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); mark_as_dependent(thd, last, current_sel, this, this); } } else if (ref == 0) { /* The current reference cannot be resolved in this query. */ /* The item was not a table field and not a reference */ my_error(ER_BAD_FIELD_ERROR, MYF(0), this->full_name(), current_thd->where); return TRUE; } /* Should be checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); mark_as_dependent(thd, last, current_sel, this, this); } } DBUG_ASSERT(*ref); /* Check if this is an incorrect reference in a group function or forward reference. Do not issue an error if this is an unnamed reference inside an Loading @@ -3716,11 +3706,12 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) set_properties(); if (ref && (*ref)->check_cols(1)) return 1; return 0; if ((*ref)->check_cols(1)) return TRUE; return FALSE; } void Item_ref::set_properties() { max_length= (*ref)->max_length; Loading