~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

Merged trunk, fixed some leftover InnoDB ICP code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
105
105
  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
106
106
 
107
107
  sql_command_flags[SQLCOM_UPDATE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
108
 
  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
109
108
  sql_command_flags[SQLCOM_INSERT]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
110
109
  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
111
110
  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
112
 
  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
113
111
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
114
112
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
115
113
 
825
823
                      unit->select_limit_cnt,
826
824
                      lex->duplicates, lex->ignore);
827
825
    break;
828
 
  case SQLCOM_UPDATE_MULTI:
829
 
  {
830
 
    assert(first_table == all_tables && first_table != 0);
831
 
    if ((res= update_precheck(session, all_tables)))
832
 
      break;
833
 
 
834
 
    if ((res= mysql_multi_update_prepare(session)))
835
 
      break;
836
 
 
837
 
    res= mysql_multi_update(session, all_tables,
838
 
                            &select_lex->item_list,
839
 
                            &lex->value_list,
840
 
                            select_lex->where,
841
 
                            select_lex->options,
842
 
                            lex->duplicates, lex->ignore, unit, select_lex);
843
 
    break;
844
 
  }
845
826
  case SQLCOM_REPLACE:
846
827
  case SQLCOM_INSERT:
847
828
  {
957
938
                       false);
958
939
    break;
959
940
  }
960
 
  case SQLCOM_DELETE_MULTI:
961
 
  {
962
 
    assert(first_table == all_tables && first_table != 0);
963
 
    TableList *aux_tables=
964
 
      (TableList *)session->lex->auxiliary_table_list.first;
965
 
    multi_delete *del_result;
966
 
 
967
 
    if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
968
 
    {
969
 
      res= 1;
970
 
      break;
971
 
    }
972
 
 
973
 
    if ((res= multi_delete_precheck(session, all_tables)))
974
 
      break;
975
 
 
976
 
    /* condition will be true on SP re-excuting */
977
 
    if (select_lex->item_list.elements != 0)
978
 
      select_lex->item_list.empty();
979
 
    if (session->add_item_to_list(new Item_null()))
980
 
      goto error;
981
 
 
982
 
    session->set_proc_info("init");
983
 
    if ((res= session->open_and_lock_tables(all_tables)))
984
 
      break;
985
 
 
986
 
    if ((res= mysql_multi_delete_prepare(session)))
987
 
      goto error;
988
 
 
989
 
    if (!session->is_fatal_error &&
990
 
        (del_result= new multi_delete(aux_tables, lex->table_count)))
991
 
    {
992
 
      res= mysql_select(session, &select_lex->ref_pointer_array,
993
 
                        select_lex->get_table_list(),
994
 
                        select_lex->with_wild,
995
 
                        select_lex->item_list,
996
 
                        select_lex->where,
997
 
                        0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
998
 
                        select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
999
 
                        del_result, unit, select_lex);
1000
 
      res|= session->is_error();
1001
 
      if (res)
1002
 
        del_result->abort();
1003
 
      delete del_result;
1004
 
    }
1005
 
    else
1006
 
      res= true;                                // Error
1007
 
    break;
1008
 
  }
1009
941
  case SQLCOM_DROP_TABLE:
1010
942
  {
1011
943
    assert(first_table == all_tables && first_table != 0);
1563
1495
}
1564
1496
 
1565
1497
 
1566
 
void mysql_init_multi_delete(LEX *lex)
1567
 
{
1568
 
  lex->sql_command=  SQLCOM_DELETE_MULTI;
1569
 
  mysql_init_select(lex);
1570
 
  lex->select_lex.select_limit= 0;
1571
 
  lex->unit.select_limit_cnt= HA_POS_ERROR;
1572
 
  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
1573
 
  lex->lock_option= TL_READ;
1574
 
  lex->query_tables= 0;
1575
 
  lex->query_tables_last= &lex->query_tables;
1576
 
}
1577
 
 
1578
 
 
1579
1498
/**
1580
1499
  Parse a query.
1581
1500
 
2575
2494
  return(false);
2576
2495
}
2577
2496
 
2578
 
/**
2579
 
  Multi delete query pre-check.
2580
 
 
2581
 
  @param session                        Thread handler
2582
 
  @param tables         Global/local table list
2583
 
 
2584
 
  @retval
2585
 
    false OK
2586
 
  @retval
2587
 
    true  error
2588
 
*/
2589
 
 
2590
 
bool multi_delete_precheck(Session *session, TableList *)
2591
 
{
2592
 
  Select_Lex *select_lex= &session->lex->select_lex;
2593
 
  TableList **save_query_tables_own_last= session->lex->query_tables_own_last;
2594
 
 
2595
 
  session->lex->query_tables_own_last= 0;
2596
 
  session->lex->query_tables_own_last= save_query_tables_own_last;
2597
 
 
2598
 
  if ((session->options & OPTION_SAFE_UPDATES) && !select_lex->where)
2599
 
  {
2600
 
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
2601
 
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
2602
 
    return(true);
2603
 
  }
2604
 
  return(false);
2605
 
}
2606
 
 
2607
 
 
2608
 
/*
2609
 
  Given a table in the source list, find a correspondent table in the
2610
 
  table references list.
2611
 
 
2612
 
  @param lex Pointer to LEX representing multi-delete.
2613
 
  @param src Source table to match.
2614
 
  @param ref Table references list.
2615
 
 
2616
 
  @remark The source table list (tables listed before the FROM clause
2617
 
  or tables listed in the FROM clause before the USING clause) may
2618
 
  contain table names or aliases that must match unambiguously one,
2619
 
  and only one, table in the target table list (table references list,
2620
 
  after FROM/USING clause).
2621
 
 
2622
 
  @return Matching table, NULL otherwise.
2623
 
*/
2624
 
 
2625
 
static TableList *multi_delete_table_match(LEX *, TableList *tbl,
2626
 
                                           TableList *tables)
2627
 
{
2628
 
  TableList *match= NULL;
2629
 
 
2630
 
  for (TableList *elem= tables; elem; elem= elem->next_local)
2631
 
  {
2632
 
    int cmp;
2633
 
 
2634
 
    if (tbl->is_fqtn && elem->is_alias)
2635
 
      continue; /* no match */
2636
 
    if (tbl->is_fqtn && elem->is_fqtn)
2637
 
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
2638
 
           strcmp(tbl->db, elem->db);
2639
 
    else if (elem->is_alias)
2640
 
      cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
2641
 
    else
2642
 
      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
2643
 
           strcmp(tbl->db, elem->db);
2644
 
 
2645
 
    if (cmp)
2646
 
      continue;
2647
 
 
2648
 
    if (match)
2649
 
    {
2650
 
      my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
2651
 
      return NULL;
2652
 
    }
2653
 
 
2654
 
    match= elem;
2655
 
  }
2656
 
 
2657
 
  if (!match)
2658
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
2659
 
 
2660
 
  return(match);
2661
 
}
2662
 
 
2663
 
 
2664
 
/**
2665
 
  Link tables in auxilary table list of multi-delete with corresponding
2666
 
  elements in main table list, and set proper locks for them.
2667
 
 
2668
 
  @param lex   pointer to LEX representing multi-delete
2669
 
 
2670
 
  @retval
2671
 
    false   success
2672
 
  @retval
2673
 
    true    error
2674
 
*/
2675
 
 
2676
 
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
2677
 
{
2678
 
  TableList *tables= (TableList*)lex->select_lex.table_list.first;
2679
 
  TableList *target_tbl;
2680
 
 
2681
 
  lex->table_count= 0;
2682
 
 
2683
 
  for (target_tbl= (TableList *)lex->auxiliary_table_list.first;
2684
 
       target_tbl; target_tbl= target_tbl->next_local)
2685
 
  {
2686
 
    lex->table_count++;
2687
 
    /* All tables in aux_tables must be found in FROM PART */
2688
 
    TableList *walk= multi_delete_table_match(lex, target_tbl, tables);
2689
 
    if (!walk)
2690
 
      return(true);
2691
 
    if (!walk->derived)
2692
 
    {
2693
 
      target_tbl->table_name= walk->table_name;
2694
 
      target_tbl->table_name_length= walk->table_name_length;
2695
 
    }
2696
 
    walk->updating= target_tbl->updating;
2697
 
    walk->lock_type= target_tbl->lock_type;
2698
 
    target_tbl->correspondent_table= walk;      // Remember corresponding table
2699
 
  }
2700
 
  return(false);
2701
 
}
2702
 
 
2703
2497
 
2704
2498
/**
2705
2499
  simple INSERT query pre-check.