@@ -7577,46 +7577,118 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
7577
7577
DBUG_RETURN (MY_TEST (thd->is_error ()));
7578
7578
}
7579
7579
7580
+ /*
7581
+ make list of leaves for a single TABLE_LIST
7582
+
7583
+ SYNOPSIS
7584
+ make_leaves_for_single_table()
7585
+ thd Thread handler
7586
+ leaves List of leaf tables to be filled
7587
+ table TABLE_LIST object to process
7588
+ full_table_list Whether to include tables from mergeable derived table/view
7589
+ */
7590
+ void make_leaves_for_single_table (THD *thd, List<TABLE_LIST> &leaves,
7591
+ TABLE_LIST *table, bool & full_table_list,
7592
+ TABLE_LIST *boundary)
7593
+ {
7594
+ if (table == boundary)
7595
+ full_table_list= !full_table_list;
7596
+ if (full_table_list && table->is_merged_derived ())
7597
+ {
7598
+ SELECT_LEX *select_lex= table->get_single_select ();
7599
+ /*
7600
+ It's safe to use select_lex->leaf_tables because all derived
7601
+ tables/views were already prepared and has their leaf_tables
7602
+ set properly.
7603
+ */
7604
+ make_leaves_list (thd, leaves, select_lex->get_table_list (),
7605
+ full_table_list, boundary);
7606
+ }
7607
+ else
7608
+ {
7609
+ leaves.push_back (table, thd->mem_root );
7610
+ }
7611
+ }
7612
+
7580
7613
7581
7614
/*
7582
7615
make list of leaves of join table tree
7583
7616
7584
7617
SYNOPSIS
7585
7618
make_leaves_list()
7586
- list pointer to pointer on list first element
7587
- tables table list
7588
- full_table_list whether to include tables from mergeable derived table/view.
7589
- we need them for checks for INSERT/UPDATE statements only.
7590
-
7591
- RETURN pointer on pointer to next_leaf of last element
7619
+ leaves List of leaf tables to be filled
7620
+ tables Table list
7621
+ full_table_list Whether to include tables from mergeable derived table/view.
7622
+ We need them for checks for INSERT/UPDATE statements only.
7592
7623
*/
7593
7624
7594
- void make_leaves_list (THD *thd, List<TABLE_LIST> &list , TABLE_LIST *tables,
7625
+ void make_leaves_list (THD *thd, List<TABLE_LIST> &leaves , TABLE_LIST *tables,
7595
7626
bool full_table_list, TABLE_LIST *boundary)
7596
7627
7597
7628
{
7598
7629
for (TABLE_LIST *table= tables; table; table= table->next_local )
7599
7630
{
7600
- if (table == boundary)
7601
- full_table_list= !full_table_list;
7602
- if (full_table_list && table->is_merged_derived ())
7603
- {
7604
- SELECT_LEX *select_lex= table->get_single_select ();
7605
- /*
7606
- It's safe to use select_lex->leaf_tables because all derived
7607
- tables/views were already prepared and has their leaf_tables
7608
- set properly.
7609
- */
7610
- make_leaves_list (thd, list, select_lex->get_table_list (),
7611
- full_table_list, boundary);
7612
- }
7613
- else
7614
- {
7615
- list.push_back (table, thd->mem_root );
7616
- }
7631
+ make_leaves_for_single_table (thd, leaves, table, full_table_list,
7632
+ boundary);
7633
+ }
7634
+ }
7635
+
7636
+
7637
+ /*
7638
+ Setup the map and other attributes for a single TABLE_LIST object
7639
+
7640
+ SYNOPSIS
7641
+ setup_table_attributes()
7642
+ thd Thread handler
7643
+ table_list TABLE_LIST object to process
7644
+ first_select_table First table participating in SELECT for INSERT..SELECT
7645
+ statements, NULL for other cases
7646
+ tablenr Serial number of the table in the SQL statement
7647
+
7648
+ RETURN
7649
+ false Success
7650
+ true Failure
7651
+ */
7652
+ bool setup_table_attributes (THD *thd, TABLE_LIST *table_list,
7653
+ TABLE_LIST *first_select_table,
7654
+ uint &tablenr)
7655
+ {
7656
+ TABLE *table= table_list->table ;
7657
+ if (table)
7658
+ table->pos_in_table_list = table_list;
7659
+ if (first_select_table && table_list->top_table () == first_select_table)
7660
+ {
7661
+ /* new counting for SELECT of INSERT ... SELECT command */
7662
+ first_select_table= 0 ;
7663
+ thd->lex ->select_lex .insert_tables = tablenr;
7664
+ tablenr= 0 ;
7665
+ }
7666
+ if (table_list->jtbm_subselect )
7667
+ {
7668
+ table_list->jtbm_table_no = tablenr;
7669
+ }
7670
+ else if (table)
7671
+ {
7672
+ table->pos_in_table_list = table_list;
7673
+ setup_table_map (table, table_list, tablenr);
7674
+
7675
+ if (table_list->process_index_hints (table))
7676
+ return true ;
7677
+ }
7678
+ tablenr++;
7679
+ /*
7680
+ We test the max tables here as we setup_table_map() should not be called
7681
+ with tablenr >= 64
7682
+ */
7683
+ if (tablenr > MAX_TABLES)
7684
+ {
7685
+ my_error (ER_TOO_MANY_TABLES, MYF (0 ), static_cast <int >(MAX_TABLES));
7686
+ return true ;
7617
7687
}
7688
+ return false ;
7618
7689
}
7619
7690
7691
+
7620
7692
/*
7621
7693
prepare tables
7622
7694
@@ -7673,7 +7745,14 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
7673
7745
leaves.empty ();
7674
7746
if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED)
7675
7747
{
7676
- make_leaves_list (thd, leaves, tables, full_table_list, first_select_table);
7748
+ /*
7749
+ For INSERT ... SELECT statements we must not include the first table
7750
+ (where the data is being inserted into) in the list of leaves
7751
+ */
7752
+ TABLE_LIST *tables_for_leaves=
7753
+ select_insert ? first_select_table : tables;
7754
+ make_leaves_list (thd, leaves, tables_for_leaves, full_table_list,
7755
+ first_select_table);
7677
7756
select_lex->prep_leaf_list_state = SELECT_LEX::READY;
7678
7757
select_lex->leaf_tables_exec .empty ();
7679
7758
}
@@ -7684,37 +7763,34 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
7684
7763
leaves.push_back (table_list, thd->mem_root );
7685
7764
}
7686
7765
7766
+ List_iterator<TABLE_LIST> ti (leaves);
7687
7767
while ((table_list= ti++))
7688
7768
{
7689
- TABLE *table= table_list->table ;
7690
- if (table)
7691
- table->pos_in_table_list = table_list;
7692
- if (first_select_table &&
7693
- table_list->top_table () == first_select_table)
7694
- {
7695
- /* new counting for SELECT of INSERT ... SELECT command */
7696
- first_select_table= 0 ;
7697
- thd->lex ->select_lex .insert_tables = tablenr;
7698
- tablenr= 0 ;
7699
- }
7700
- if (table_list->jtbm_subselect )
7701
- {
7702
- table_list->jtbm_table_no = tablenr;
7703
- }
7704
- else if (table)
7705
- {
7706
- table->pos_in_table_list = table_list;
7707
- setup_table_map (table, table_list, tablenr);
7769
+ if (setup_table_attributes (thd, table_list, first_select_table, tablenr))
7770
+ DBUG_RETURN (1 );
7771
+ }
7708
7772
7709
- if (table_list->process_index_hints (table))
7773
+ if (select_insert)
7774
+ {
7775
+ /*
7776
+ The table/view in which the data is inserted must not be included into
7777
+ the leaf_tables list. But we need this table/view to setup attributes
7778
+ for it. So build a temporary list of leaves and setup attributes for
7779
+ the tables included
7780
+ */
7781
+ List<TABLE_LIST> leaves;
7782
+ TABLE_LIST *table= tables;
7783
+
7784
+ make_leaves_for_single_table (thd, leaves, table, full_table_list,
7785
+ first_select_table);
7786
+
7787
+ List_iterator<TABLE_LIST> ti (leaves);
7788
+ while ((table_list= ti++))
7789
+ {
7790
+ if (setup_table_attributes (thd, table_list, first_select_table,
7791
+ tablenr))
7710
7792
DBUG_RETURN (1 );
7711
7793
}
7712
- tablenr++;
7713
- }
7714
- if (tablenr > MAX_TABLES)
7715
- {
7716
- my_error (ER_TOO_MANY_TABLES,MYF (0 ), static_cast <int >(MAX_TABLES));
7717
- DBUG_RETURN (1 );
7718
7794
}
7719
7795
}
7720
7796
else
0 commit comments