~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Brian Aker
  • Date: 2009-08-04 06:21:17 UTC
  • mfrom: (1108.2.2 merge)
  • Revision ID: brian@gaz-20090804062117-fef8x6y3ydzrvab3
Merge Brian

Show diffs side-by-side

added added

removed removed

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