summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc61
1 files changed, 37 insertions, 24 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index eb54c44fa47..ed20d98c3a8 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3258,8 +3258,8 @@ end_with_restore_list:
/* Skip first table, which is the table we are inserting in */
TABLE_LIST *second_table= first_table->next_local;
select_lex->table_list.first= (byte*) second_table;
- select_lex->context.table_list= second_table;
- select_lex->context.first_name_resolution_table= second_table;
+ select_lex->context.table_list=
+ select_lex->context.first_name_resolution_table= second_table;
res= mysql_insert_select_prepare(thd);
if (!res && (result= new select_insert(first_table, first_table->table,
&lex->field_list,
@@ -3274,8 +3274,8 @@ end_with_restore_list:
which in turn resets context.table_list and
context.first_name_resolution_table.
*/
- select_lex->context.table_list= first_table->next_local;
- select_lex->context.first_name_resolution_table= first_table->next_local;
+ select_lex->context.table_list=
+ select_lex->context.first_name_resolution_table= second_table;
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
delete result;
}
@@ -6016,6 +6016,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
char *alias_str;
LEX *lex= thd->lex;
DBUG_ENTER("add_table_to_list");
+ LINT_INIT(previous_table_ref);
if (!table)
DBUG_RETURN(0); // End of memory
@@ -6111,9 +6112,23 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
/* Store the table reference preceding the current one. */
if (table_list.elements > 0)
{
- previous_table_ref= (TABLE_LIST*) table_list.next;
+ /*
+ table_list.next points to the last inserted TABLE_LIST->next_local'
+ element
+ */
+ previous_table_ref= (TABLE_LIST*) (table_list.next -
+ offsetof(TABLE_LIST, next_local));
DBUG_ASSERT(previous_table_ref);
+ /*
+ Set next_name_resolution_table of the previous table reference to point
+ to the current table reference. In effect the list
+ TABLE_LIST::next_name_resolution_table coincides with
+ TABLE_LIST::next_local. Later this may be changed in
+ store_top_level_join_columns() for NATURAL/USING joins.
+ */
+ previous_table_ref->next_name_resolution_table= ptr;
}
+
/*
Link the current table reference in a local list (list for current select).
Notice that as a side effect here we set the next_local field of the
@@ -6121,15 +6136,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
list 'table_list'.
*/
table_list.link_in_list((byte*) ptr, (byte**) &ptr->next_local);
- /*
- Set next_name_resolution_table of the previous table reference to point to
- the current table reference. In effect the list
- TABLE_LIST::next_name_resolution_table coincides with
- TABLE_LIST::next_local. Later this may be changed in
- store_top_level_join_columns() for NATURAL/USING joins.
- */
- if (table_list.elements > 1)
- previous_table_ref->next_name_resolution_table= ptr;
ptr->next_name_resolution_table= NULL;
/* Link table in global list (all used tables) */
lex->add_to_query_tables(ptr);
@@ -6164,10 +6170,12 @@ bool st_select_lex::init_nested_join(THD *thd)
NESTED_JOIN *nested_join;
DBUG_ENTER("init_nested_join");
- if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))) ||
- !(nested_join= ptr->nested_join=
- (NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
+ if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
+ sizeof(NESTED_JOIN))))
DBUG_RETURN(1);
+ nested_join= ptr->nested_join=
+ ((NESTED_JOIN*) ((byte*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
+
join_list->push_front(ptr);
ptr->embedding= embedding;
ptr->join_list= join_list;
@@ -6235,25 +6243,30 @@ TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
The function nest last join operation as if it was enclosed in braces.
RETURN VALUE
- Pointer to TABLE_LIST element created for the new nested join, if success
- 0, otherwise
+ 0 Error
+ # Pointer to TABLE_LIST element created for the new nested join
+
*/
TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
{
TABLE_LIST *ptr;
NESTED_JOIN *nested_join;
+ List<TABLE_LIST> *embedded_list;
DBUG_ENTER("nest_last_join");
- if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))) ||
- !(nested_join= ptr->nested_join=
- (NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
+ if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
+ sizeof(NESTED_JOIN))))
DBUG_RETURN(0);
+ nested_join= ptr->nested_join=
+ ((NESTED_JOIN*) ((byte*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
+
ptr->embedding= embedding;
ptr->join_list= join_list;
- List<TABLE_LIST> *embedded_list= &nested_join->join_list;
+ embedded_list= &nested_join->join_list;
embedded_list->empty();
- for (int i=0; i < 2; i++)
+
+ for (uint i=0; i < 2; i++)
{
TABLE_LIST *table= join_list->pop();
table->join_list= embedded_list;