Drizzled Public API Documentation

pars0pars.cc
00001 /*****************************************************************************
00002 
00003 Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
00004 
00005 This program is free software; you can redistribute it and/or modify it under
00006 the terms of the GNU General Public License as published by the Free Software
00007 Foundation; version 2 of the License.
00008 
00009 This program is distributed in the hope that it will be useful, but WITHOUT
00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00012 
00013 You should have received a copy of the GNU General Public License along with
00014 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
00015 St, Fifth Floor, Boston, MA 02110-1301 USA
00016 
00017 *****************************************************************************/
00018 
00019 /**************************************************/
00026 /* Historical note: Innobase executed its first SQL string (CREATE TABLE)
00027 on 1/27/1998 */
00028 
00029 #include "pars0pars.h"
00030 
00031 #ifdef UNIV_NONINL
00032 #include "pars0pars.ic"
00033 #endif
00034 
00035 #include "row0sel.h"
00036 #include "row0ins.h"
00037 #include "row0upd.h"
00038 #include "dict0dict.h"
00039 #include "dict0mem.h"
00040 #include "dict0crea.h"
00041 #include "que0que.h"
00042 #ifndef PARS0GRM_H
00043 # define PARS0GRM_H
00044 # include "pars0grm.hh"
00045 #endif
00046 #include "pars0opt.h"
00047 #include "data0data.h"
00048 #include "data0type.h"
00049 #include "trx0trx.h"
00050 #include "trx0roll.h"
00051 #include "lock0lock.h"
00052 #include "eval0eval.h"
00053 
00054 #ifdef UNIV_SQL_DEBUG
00055 
00057 UNIV_INTERN ibool pars_print_lexed  = FALSE;
00058 #endif /* UNIV_SQL_DEBUG */
00059 
00060 /* Global variable used while parsing a single procedure or query : the code is
00061 NOT re-entrant */
00062 UNIV_INTERN sym_tab_t*  pars_sym_tab_global;
00063 
00064 /* Global variables used to denote certain reserved words, used in
00065 constructing the parsing tree */
00066 
00067 UNIV_INTERN pars_res_word_t pars_to_char_token = {PARS_TO_CHAR_TOKEN};
00068 UNIV_INTERN pars_res_word_t pars_to_number_token = {PARS_TO_NUMBER_TOKEN};
00069 UNIV_INTERN pars_res_word_t pars_to_binary_token = {PARS_TO_BINARY_TOKEN};
00070 UNIV_INTERN pars_res_word_t pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};
00071 UNIV_INTERN pars_res_word_t pars_substr_token = {PARS_SUBSTR_TOKEN};
00072 UNIV_INTERN pars_res_word_t pars_replstr_token = {PARS_REPLSTR_TOKEN};
00073 UNIV_INTERN pars_res_word_t pars_concat_token = {PARS_CONCAT_TOKEN};
00074 UNIV_INTERN pars_res_word_t pars_instr_token = {PARS_INSTR_TOKEN};
00075 UNIV_INTERN pars_res_word_t pars_length_token = {PARS_LENGTH_TOKEN};
00076 UNIV_INTERN pars_res_word_t pars_sysdate_token = {PARS_SYSDATE_TOKEN};
00077 UNIV_INTERN pars_res_word_t pars_printf_token = {PARS_PRINTF_TOKEN};
00078 UNIV_INTERN pars_res_word_t pars_assert_token = {PARS_ASSERT_TOKEN};
00079 UNIV_INTERN pars_res_word_t pars_rnd_token = {PARS_RND_TOKEN};
00080 UNIV_INTERN pars_res_word_t pars_rnd_str_token = {PARS_RND_STR_TOKEN};
00081 UNIV_INTERN pars_res_word_t pars_count_token = {PARS_COUNT_TOKEN};
00082 UNIV_INTERN pars_res_word_t pars_sum_token = {PARS_SUM_TOKEN};
00083 UNIV_INTERN pars_res_word_t pars_distinct_token = {PARS_DISTINCT_TOKEN};
00084 UNIV_INTERN pars_res_word_t pars_binary_token = {PARS_BINARY_TOKEN};
00085 UNIV_INTERN pars_res_word_t pars_blob_token = {PARS_BLOB_TOKEN};
00086 UNIV_INTERN pars_res_word_t pars_int_token = {PARS_INT_TOKEN};
00087 UNIV_INTERN pars_res_word_t pars_char_token = {PARS_CHAR_TOKEN};
00088 UNIV_INTERN pars_res_word_t pars_float_token = {PARS_FLOAT_TOKEN};
00089 UNIV_INTERN pars_res_word_t pars_update_token = {PARS_UPDATE_TOKEN};
00090 UNIV_INTERN pars_res_word_t pars_asc_token = {PARS_ASC_TOKEN};
00091 UNIV_INTERN pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN};
00092 UNIV_INTERN pars_res_word_t pars_open_token = {PARS_OPEN_TOKEN};
00093 UNIV_INTERN pars_res_word_t pars_close_token = {PARS_CLOSE_TOKEN};
00094 UNIV_INTERN pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
00095 UNIV_INTERN pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
00096 UNIV_INTERN pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
00097 
00099 UNIV_INTERN ulint pars_star_denoter = 12345678;
00100 
00101 
00102 /*********************************************************************/
00105 static
00106 ulint
00107 pars_func_get_class(
00108 /*================*/
00109   int func) 
00110 {
00111   switch (func) {
00112   case '+': case '-': case '*': case '/':
00113     return(PARS_FUNC_ARITH);
00114 
00115   case '=': case '<': case '>':
00116   case PARS_GE_TOKEN: case PARS_LE_TOKEN: case PARS_NE_TOKEN:
00117     return(PARS_FUNC_CMP);
00118 
00119   case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN:
00120     return(PARS_FUNC_LOGICAL);
00121 
00122   case PARS_COUNT_TOKEN: case PARS_SUM_TOKEN:
00123     return(PARS_FUNC_AGGREGATE);
00124 
00125   case PARS_TO_CHAR_TOKEN:
00126   case PARS_TO_NUMBER_TOKEN:
00127   case PARS_TO_BINARY_TOKEN:
00128   case PARS_BINARY_TO_NUMBER_TOKEN:
00129   case PARS_SUBSTR_TOKEN:
00130   case PARS_CONCAT_TOKEN:
00131   case PARS_LENGTH_TOKEN:
00132   case PARS_INSTR_TOKEN:
00133   case PARS_SYSDATE_TOKEN:
00134   case PARS_NOTFOUND_TOKEN:
00135   case PARS_PRINTF_TOKEN:
00136   case PARS_ASSERT_TOKEN:
00137   case PARS_RND_TOKEN:
00138   case PARS_RND_STR_TOKEN:
00139   case PARS_REPLSTR_TOKEN:
00140     return(PARS_FUNC_PREDEFINED);
00141 
00142   default:
00143     return(PARS_FUNC_OTHER);
00144   }
00145 }
00146 
00147 /*********************************************************************/
00150 static
00151 func_node_t*
00152 pars_func_low(
00153 /*==========*/
00154   int   func, 
00155   que_node_t* arg)  
00156 {
00157   func_node_t*  node;
00158 
00159   node = static_cast<func_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t)));
00160 
00161   node->common.type = QUE_NODE_FUNC;
00162   dfield_set_data(&(node->common.val), NULL, 0);
00163   node->common.val_buf_size = 0;
00164 
00165   node->func = func;
00166 
00167   node->func_class = pars_func_get_class(func);
00168 
00169   node->args = arg;
00170 
00171   UT_LIST_ADD_LAST(func_node_list, pars_sym_tab_global->func_node_list,
00172        node);
00173   return(node);
00174 }
00175 
00176 /*********************************************************************/
00179 UNIV_INTERN
00180 func_node_t*
00181 pars_func(
00182 /*======*/
00183   que_node_t* res_word,
00184   que_node_t* arg)  
00185 {
00186   return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
00187 }
00188 
00189 /*********************************************************************/
00192 UNIV_INTERN
00193 func_node_t*
00194 pars_op(
00195 /*====*/
00196   int   func, 
00197   que_node_t* arg1, 
00198   que_node_t* arg2) 
00200 {
00201   que_node_list_add_last(NULL, arg1);
00202 
00203   if (arg2) {
00204     que_node_list_add_last(arg1, arg2);
00205   }
00206 
00207   return(pars_func_low(func, arg1));
00208 }
00209 
00210 /*********************************************************************/
00213 UNIV_INTERN
00214 order_node_t*
00215 pars_order_by(
00216 /*==========*/
00217   sym_node_t* column, 
00218   pars_res_word_t* asc) 
00219 {
00220   order_node_t* node;
00221 
00222   node = static_cast<order_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(order_node_t)));
00223 
00224   node->common.type = QUE_NODE_ORDER;
00225 
00226   node->column = column;
00227 
00228   if (asc == &pars_asc_token) {
00229     node->asc = TRUE;
00230   } else {
00231     ut_a(asc == &pars_desc_token);
00232     node->asc = FALSE;
00233   }
00234 
00235   return(node);
00236 }
00237 
00238 /*********************************************************************/
00242 static
00243 ibool
00244 pars_is_string_type(
00245 /*================*/
00246   ulint mtype)  
00247 {
00248   switch (mtype) {
00249   case DATA_VARCHAR: case DATA_CHAR:
00250   case DATA_FIXBINARY: case DATA_BINARY:
00251     return(TRUE);
00252   }
00253 
00254   return(FALSE);
00255 }
00256 
00257 /*********************************************************************/
00260 static
00261 void
00262 pars_resolve_func_data_type(
00263 /*========================*/
00264   func_node_t*  node) 
00265 {
00266   que_node_t* arg;
00267 
00268   ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
00269 
00270   arg = node->args;
00271 
00272   switch (node->func) {
00273   case PARS_SUM_TOKEN:
00274   case '+': case '-': case '*': case '/':
00275     /* Inherit the data type from the first argument (which must
00276     not be the SQL null literal whose type is DATA_ERROR) */
00277 
00278     dtype_copy(que_node_get_data_type(node),
00279          que_node_get_data_type(arg));
00280 
00281     ut_a(dtype_get_mtype(que_node_get_data_type(node))
00282          == DATA_INT);
00283     break;
00284 
00285   case PARS_COUNT_TOKEN:
00286     ut_a(arg);
00287     dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
00288     break;
00289 
00290   case PARS_TO_CHAR_TOKEN:
00291   case PARS_RND_STR_TOKEN:
00292     ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
00293     dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
00294         DATA_ENGLISH, 0);
00295     break;
00296 
00297   case PARS_TO_BINARY_TOKEN:
00298     if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
00299       dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
00300           DATA_ENGLISH, 0);
00301     } else {
00302       dtype_set(que_node_get_data_type(node), DATA_BINARY,
00303           0, 0);
00304     }
00305     break;
00306 
00307   case PARS_TO_NUMBER_TOKEN:
00308   case PARS_BINARY_TO_NUMBER_TOKEN:
00309   case PARS_LENGTH_TOKEN:
00310   case PARS_INSTR_TOKEN:
00311     ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
00312     dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
00313     break;
00314 
00315   case PARS_SYSDATE_TOKEN:
00316     ut_a(arg == NULL);
00317     dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
00318     break;
00319 
00320   case PARS_SUBSTR_TOKEN:
00321   case PARS_CONCAT_TOKEN:
00322     ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
00323     dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
00324         DATA_ENGLISH, 0);
00325     break;
00326 
00327   case '>': case '<': case '=':
00328   case PARS_GE_TOKEN:
00329   case PARS_LE_TOKEN:
00330   case PARS_NE_TOKEN:
00331   case PARS_AND_TOKEN:
00332   case PARS_OR_TOKEN:
00333   case PARS_NOT_TOKEN:
00334   case PARS_NOTFOUND_TOKEN:
00335 
00336     /* We currently have no iboolean type: use integer type */
00337     dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
00338     break;
00339 
00340   case PARS_RND_TOKEN:
00341     ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
00342     dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
00343     break;
00344 
00345   default:
00346     ut_error;
00347   }
00348 }
00349 
00350 /*********************************************************************/
00353 static
00354 void
00355 pars_resolve_exp_variables_and_types(
00356 /*=================================*/
00357   sel_node_t* select_node,  
00361   que_node_t* exp_node) 
00362 {
00363   func_node_t*  func_node;
00364   que_node_t* arg;
00365   sym_node_t* sym_node;
00366   sym_node_t* node;
00367 
00368   ut_a(exp_node);
00369 
00370   if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
00371     func_node = static_cast<func_node_t *>(exp_node);
00372 
00373     arg = func_node->args;
00374 
00375     while (arg) {
00376       pars_resolve_exp_variables_and_types(select_node, arg);
00377 
00378       arg = que_node_get_next(arg);
00379     }
00380 
00381     pars_resolve_func_data_type(func_node);
00382 
00383     return;
00384   }
00385 
00386   ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
00387 
00388   sym_node = static_cast<sym_node_t *>(exp_node);
00389 
00390   if (sym_node->resolved) {
00391 
00392     return;
00393   }
00394 
00395   /* Not resolved yet: look in the symbol table for a variable
00396   or a cursor or a function with the same name */
00397 
00398   node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
00399 
00400   while (node) {
00401     if (node->resolved
00402         && ((node->token_type == SYM_VAR)
00403       || (node->token_type == SYM_CURSOR)
00404       || (node->token_type == SYM_FUNCTION))
00405         && node->name
00406         && (sym_node->name_len == node->name_len)
00407         && (ut_memcmp(sym_node->name, node->name,
00408           node->name_len) == 0)) {
00409 
00410       /* Found a variable or a cursor declared with
00411       the same name */
00412 
00413       break;
00414     }
00415 
00416     node = UT_LIST_GET_NEXT(sym_list, node);
00417   }
00418 
00419   if (!node) {
00420     fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",
00421       sym_node->name);
00422   }
00423 
00424   ut_a(node);
00425 
00426   sym_node->resolved = TRUE;
00427   sym_node->token_type = SYM_IMPLICIT_VAR;
00428   sym_node->alias = node;
00429   sym_node->indirection = node;
00430 
00431   if (select_node) {
00432     UT_LIST_ADD_LAST(col_var_list, select_node->copy_variables,
00433          sym_node);
00434   }
00435 
00436   dfield_set_type(que_node_get_val(sym_node),
00437       que_node_get_data_type(node));
00438 }
00439 
00440 /*********************************************************************/
00444 static
00445 void
00446 pars_resolve_exp_list_variables_and_types(
00447 /*======================================*/
00448   sel_node_t* select_node,  
00449   que_node_t* exp_node) 
00451 {
00452   while (exp_node) {
00453     pars_resolve_exp_variables_and_types(select_node, exp_node);
00454 
00455     exp_node = que_node_get_next(exp_node);
00456   }
00457 }
00458 
00459 /*********************************************************************/
00461 static
00462 void
00463 pars_resolve_exp_columns(
00464 /*=====================*/
00465   sym_node_t* table_node, 
00466   que_node_t* exp_node) 
00467 {
00468   func_node_t*  func_node;
00469   que_node_t* arg;
00470   sym_node_t* sym_node;
00471   dict_table_t* table;
00472   sym_node_t* t_node;
00473   ulint   n_cols;
00474   ulint   i;
00475 
00476   ut_a(exp_node);
00477 
00478   if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
00479     func_node = static_cast<func_node_t *>(exp_node);
00480 
00481     arg = func_node->args;
00482 
00483     while (arg) {
00484       pars_resolve_exp_columns(table_node, arg);
00485 
00486       arg = que_node_get_next(arg);
00487     }
00488 
00489     return;
00490   }
00491 
00492   ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
00493 
00494   sym_node = static_cast<sym_node_t *>(exp_node);
00495 
00496   if (sym_node->resolved) {
00497 
00498     return;
00499   }
00500 
00501   /* Not resolved yet: look in the table list for a column with the
00502   same name */
00503 
00504   t_node = table_node;
00505 
00506   while (t_node) {
00507     table = t_node->table;
00508 
00509     n_cols = dict_table_get_n_cols(table);
00510 
00511     for (i = 0; i < n_cols; i++) {
00512       const dict_col_t* col
00513         = dict_table_get_nth_col(table, i);
00514       const char*   col_name
00515         = dict_table_get_col_name(table, i);
00516 
00517       if ((sym_node->name_len == ut_strlen(col_name))
00518           && (0 == ut_memcmp(sym_node->name, col_name,
00519                  sym_node->name_len))) {
00520         /* Found */
00521         sym_node->resolved = TRUE;
00522         sym_node->token_type = SYM_COLUMN;
00523         sym_node->table = table;
00524         sym_node->col_no = i;
00525         sym_node->prefetch_buf = NULL;
00526 
00527         dict_col_copy_type(
00528           col,
00529           dfield_get_type(&sym_node
00530               ->common.val));
00531 
00532         return;
00533       }
00534     }
00535 
00536     t_node = static_cast<sym_node_t *>(que_node_get_next(t_node));
00537   }
00538 }
00539 
00540 /*********************************************************************/
00542 static
00543 void
00544 pars_resolve_exp_list_columns(
00545 /*==========================*/
00546   sym_node_t* table_node, 
00547   que_node_t* exp_node) 
00549 {
00550   while (exp_node) {
00551     pars_resolve_exp_columns(table_node, exp_node);
00552 
00553     exp_node = que_node_get_next(exp_node);
00554   }
00555 }
00556 
00557 /*********************************************************************/
00559 static
00560 void
00561 pars_retrieve_table_def(
00562 /*====================*/
00563   sym_node_t* sym_node) 
00564 {
00565   const char* table_name;
00566 
00567   ut_a(sym_node);
00568   ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
00569 
00570   sym_node->resolved = TRUE;
00571   sym_node->token_type = SYM_TABLE;
00572 
00573   table_name = (const char*) sym_node->name;
00574 
00575   sym_node->table = dict_table_get_low(table_name);
00576 
00577   ut_a(sym_node->table);
00578 }
00579 
00580 /*********************************************************************/
00583 static
00584 ulint
00585 pars_retrieve_table_list_defs(
00586 /*==========================*/
00587   sym_node_t* sym_node) 
00588 {
00589   ulint   count   = 0;
00590 
00591   if (sym_node == NULL) {
00592 
00593     return(count);
00594   }
00595 
00596   while (sym_node) {
00597     pars_retrieve_table_def(sym_node);
00598 
00599     count++;
00600 
00601     sym_node = static_cast<sym_node_t *>(que_node_get_next(sym_node));
00602   }
00603 
00604   return(count);
00605 }
00606 
00607 /*********************************************************************/
00609 static
00610 void
00611 pars_select_all_columns(
00612 /*====================*/
00613   sel_node_t* select_node)  
00615 {
00616   sym_node_t* col_node;
00617   sym_node_t* table_node;
00618   dict_table_t* table;
00619   ulint   i;
00620 
00621   select_node->select_list = NULL;
00622 
00623   table_node = select_node->table_list;
00624 
00625   while (table_node) {
00626     table = table_node->table;
00627 
00628     for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
00629       const char* col_name = dict_table_get_col_name(
00630         table, i);
00631 
00632       col_node = sym_tab_add_id(pars_sym_tab_global,
00633               (byte*)col_name,
00634               ut_strlen(col_name));
00635 
00636       select_node->select_list = que_node_list_add_last(
00637         select_node->select_list, col_node);
00638     }
00639 
00640     table_node = static_cast<sym_node_t *>(que_node_get_next(table_node));
00641   }
00642 }
00643 
00644 /*********************************************************************/
00648 UNIV_INTERN
00649 sel_node_t*
00650 pars_select_list(
00651 /*=============*/
00652   que_node_t* select_list,  
00653   sym_node_t* into_list)  
00654 {
00655   sel_node_t* node;
00656 
00657   node = sel_node_create(pars_sym_tab_global->heap);
00658 
00659   node->select_list = select_list;
00660   node->into_list = into_list;
00661 
00662   pars_resolve_exp_list_variables_and_types(NULL, into_list);
00663 
00664   return(node);
00665 }
00666 
00667 /*********************************************************************/
00670 static
00671 void
00672 pars_check_aggregate(
00673 /*=================*/
00674   sel_node_t* select_node)  
00676 {
00677   que_node_t* exp_node;
00678   func_node_t*  func_node;
00679   ulint   n_nodes     = 0;
00680   ulint   n_aggregate_nodes = 0;
00681 
00682   exp_node = select_node->select_list;
00683 
00684   while (exp_node) {
00685 
00686     n_nodes++;
00687 
00688     if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
00689 
00690       func_node = static_cast<func_node_t *>(exp_node);
00691 
00692       if (func_node->func_class == PARS_FUNC_AGGREGATE) {
00693 
00694         n_aggregate_nodes++;
00695       }
00696     }
00697 
00698     exp_node = que_node_get_next(exp_node);
00699   }
00700 
00701   if (n_aggregate_nodes > 0) {
00702     ut_a(n_nodes == n_aggregate_nodes);
00703 
00704     select_node->is_aggregate = TRUE;
00705   } else {
00706     select_node->is_aggregate = FALSE;
00707   }
00708 }
00709 
00710 /*********************************************************************/
00713 UNIV_INTERN
00714 sel_node_t*
00715 pars_select_statement(
00716 /*==================*/
00717   sel_node_t* select_node,  
00719   sym_node_t* table_list, 
00720   que_node_t* search_cond,  
00721   pars_res_word_t* for_update,  
00722   pars_res_word_t* lock_shared, 
00723   order_node_t* order_by) 
00724 {
00725   select_node->state = SEL_NODE_OPEN;
00726 
00727   select_node->table_list = table_list;
00728   select_node->n_tables = pars_retrieve_table_list_defs(table_list);
00729 
00730   if (select_node->select_list == &pars_star_denoter) {
00731 
00732     /* SELECT * FROM ... */
00733     pars_select_all_columns(select_node);
00734   }
00735 
00736   if (select_node->into_list) {
00737     ut_a(que_node_list_get_len(select_node->into_list)
00738          == que_node_list_get_len(select_node->select_list));
00739   }
00740 
00741   UT_LIST_INIT(select_node->copy_variables);
00742 
00743   pars_resolve_exp_list_columns(table_list, select_node->select_list);
00744   pars_resolve_exp_list_variables_and_types(select_node,
00745               select_node->select_list);
00746   pars_check_aggregate(select_node);
00747 
00748   select_node->search_cond = search_cond;
00749 
00750   if (search_cond) {
00751     pars_resolve_exp_columns(table_list, search_cond);
00752     pars_resolve_exp_variables_and_types(select_node, search_cond);
00753   }
00754 
00755   if (for_update) {
00756     ut_a(!lock_shared);
00757 
00758     select_node->set_x_locks = TRUE;
00759     select_node->row_lock_mode = LOCK_X;
00760 
00761     select_node->consistent_read = FALSE;
00762     select_node->read_view = NULL;
00763   } else if (lock_shared){
00764     select_node->set_x_locks = FALSE;
00765     select_node->row_lock_mode = LOCK_S;
00766 
00767     select_node->consistent_read = FALSE;
00768     select_node->read_view = NULL;
00769   } else {
00770     select_node->set_x_locks = FALSE;
00771     select_node->row_lock_mode = LOCK_S;
00772 
00773     select_node->consistent_read = TRUE;
00774   }
00775 
00776   select_node->order_by = order_by;
00777 
00778   if (order_by) {
00779     pars_resolve_exp_columns(table_list, order_by->column);
00780   }
00781 
00782   /* The final value of the following fields depend on the environment
00783   where the select statement appears: */
00784 
00785   select_node->can_get_updated = FALSE;
00786   select_node->explicit_cursor = NULL;
00787 
00788   opt_search_plan(select_node);
00789 
00790   return(select_node);
00791 }
00792 
00793 /*********************************************************************/
00796 UNIV_INTERN
00797 que_node_t*
00798 pars_cursor_declaration(
00799 /*====================*/
00800   sym_node_t* sym_node, 
00802   sel_node_t* select_node)  
00803 {
00804   sym_node->resolved = TRUE;
00805   sym_node->token_type = SYM_CURSOR;
00806   sym_node->cursor_def = select_node;
00807 
00808   select_node->state = SEL_NODE_CLOSED;
00809   select_node->explicit_cursor = sym_node;
00810 
00811   return(sym_node);
00812 }
00813 
00814 /*********************************************************************/
00817 UNIV_INTERN
00818 que_node_t*
00819 pars_function_declaration(
00820 /*======================*/
00821   sym_node_t* sym_node) 
00823 {
00824   sym_node->resolved = TRUE;
00825   sym_node->token_type = SYM_FUNCTION;
00826 
00827   /* Check that the function exists. */
00828   ut_a(pars_info_get_user_func(pars_sym_tab_global->info,
00829              sym_node->name));
00830 
00831   return(sym_node);
00832 }
00833 
00834 /*********************************************************************/
00837 UNIV_INTERN
00838 upd_node_t*
00839 pars_update_statement_start(
00840 /*========================*/
00841   ibool   is_delete,  
00842   sym_node_t* table_sym,  
00843   col_assign_node_t* col_assign_list)
00845 {
00846   upd_node_t* node;
00847 
00848   node = upd_node_create(pars_sym_tab_global->heap);
00849 
00850   node->is_delete = is_delete;
00851 
00852   node->table_sym = table_sym;
00853   node->col_assign_list = col_assign_list;
00854 
00855   return(node);
00856 }
00857 
00858 /*********************************************************************/
00861 UNIV_INTERN
00862 col_assign_node_t*
00863 pars_column_assignment(
00864 /*===================*/
00865   sym_node_t* column, 
00866   que_node_t* exp)  
00867 {
00868   col_assign_node_t*  node;
00869 
00870   node = static_cast<col_assign_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
00871             sizeof(col_assign_node_t)));
00872   node->common.type = QUE_NODE_COL_ASSIGNMENT;
00873 
00874   node->col = column;
00875   node->val = exp;
00876 
00877   return(node);
00878 }
00879 
00880 /*********************************************************************/
00882 static
00883 void
00884 pars_process_assign_list(
00885 /*=====================*/
00886   upd_node_t* node) 
00887 {
00888   col_assign_node_t*  col_assign_list;
00889   sym_node_t*   table_sym;
00890   col_assign_node_t*  assign_node;
00891   upd_field_t*    upd_field;
00892   dict_index_t*   clust_index;
00893   sym_node_t*   col_sym;
00894   ulint     changes_ord_field;
00895   ulint     changes_field_size;
00896   ulint     n_assigns;
00897   ulint     i;
00898 
00899   table_sym = node->table_sym;
00900   col_assign_list = static_cast<col_assign_node_t *>(node->col_assign_list);
00901   clust_index = dict_table_get_first_index(node->table);
00902 
00903   assign_node = col_assign_list;
00904   n_assigns = 0;
00905 
00906   while (assign_node) {
00907     pars_resolve_exp_columns(table_sym, assign_node->col);
00908     pars_resolve_exp_columns(table_sym, assign_node->val);
00909     pars_resolve_exp_variables_and_types(NULL, assign_node->val);
00910 #if 0
00911     ut_a(dtype_get_mtype(
00912            dfield_get_type(que_node_get_val(
00913                  assign_node->col)))
00914          == dtype_get_mtype(
00915            dfield_get_type(que_node_get_val(
00916                  assign_node->val))));
00917 #endif
00918 
00919     /* Add to the update node all the columns found in assignment
00920     values as columns to copy: therefore, TRUE */
00921 
00922     opt_find_all_cols(TRUE, clust_index, &(node->columns), NULL,
00923           assign_node->val);
00924     n_assigns++;
00925 
00926     assign_node = static_cast<col_assign_node_t *>(que_node_get_next(assign_node));
00927   }
00928 
00929   node->update = upd_create(n_assigns, pars_sym_tab_global->heap);
00930 
00931   assign_node = col_assign_list;
00932 
00933   changes_field_size = UPD_NODE_NO_SIZE_CHANGE;
00934 
00935   for (i = 0; i < n_assigns; i++) {
00936     upd_field = upd_get_nth_field(node->update, i);
00937 
00938     col_sym = assign_node->col;
00939 
00940     upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
00941                  clust_index, col_sym->col_no),
00942                clust_index, NULL);
00943     upd_field->exp = assign_node->val;
00944 
00945     if (!dict_col_get_fixed_size(
00946           dict_index_get_nth_col(clust_index,
00947                upd_field->field_no),
00948           dict_table_is_comp(node->table))) {
00949       changes_field_size = 0;
00950     }
00951 
00952     assign_node = static_cast<col_assign_node_t *>(que_node_get_next(assign_node));
00953   }
00954 
00955   /* Find out if the update can modify an ordering field in any index */
00956 
00957   changes_ord_field = UPD_NODE_NO_ORD_CHANGE;
00958 
00959   if (row_upd_changes_some_index_ord_field_binary(node->table,
00960               node->update)) {
00961     changes_ord_field = 0;
00962   }
00963 
00964   node->cmpl_info = changes_ord_field | changes_field_size;
00965 }
00966 
00967 /*********************************************************************/
00970 UNIV_INTERN
00971 upd_node_t*
00972 pars_update_statement(
00973 /*==================*/
00974   upd_node_t* node,   
00975   sym_node_t* cursor_sym, 
00977   que_node_t* search_cond)  
00978 {
00979   sym_node_t* table_sym;
00980   sel_node_t* sel_node;
00981   plan_t*   plan;
00982 
00983   table_sym = node->table_sym;
00984 
00985   pars_retrieve_table_def(table_sym);
00986   node->table = table_sym->table;
00987 
00988   UT_LIST_INIT(node->columns);
00989 
00990   /* Make the single table node into a list of table nodes of length 1 */
00991 
00992   que_node_list_add_last(NULL, table_sym);
00993 
00994   if (cursor_sym) {
00995     pars_resolve_exp_variables_and_types(NULL, cursor_sym);
00996 
00997     sel_node = cursor_sym->alias->cursor_def;
00998 
00999     node->searched_update = FALSE;
01000   } else {
01001     sel_node = pars_select_list(NULL, NULL);
01002 
01003     pars_select_statement(sel_node, table_sym, search_cond, NULL,
01004               &pars_share_token, NULL);
01005     node->searched_update = TRUE;
01006     sel_node->common.parent = node;
01007   }
01008 
01009   node->select = sel_node;
01010 
01011   ut_a(!node->is_delete || (node->col_assign_list == NULL));
01012   ut_a(node->is_delete || (node->col_assign_list != NULL));
01013 
01014   if (node->is_delete) {
01015     node->cmpl_info = 0;
01016   } else {
01017     pars_process_assign_list(node);
01018   }
01019 
01020   if (node->searched_update) {
01021     node->has_clust_rec_x_lock = TRUE;
01022     sel_node->set_x_locks = TRUE;
01023     sel_node->row_lock_mode = LOCK_X;
01024   } else {
01025     node->has_clust_rec_x_lock = sel_node->set_x_locks;
01026   }
01027 
01028   ut_a(sel_node->n_tables == 1);
01029   ut_a(sel_node->consistent_read == FALSE);
01030   ut_a(sel_node->order_by == NULL);
01031   ut_a(sel_node->is_aggregate == FALSE);
01032 
01033   sel_node->can_get_updated = TRUE;
01034 
01035   node->state = UPD_NODE_UPDATE_CLUSTERED;
01036 
01037   plan = sel_node_get_nth_plan(sel_node, 0);
01038 
01039   plan->no_prefetch = TRUE;
01040 
01041   if (!dict_index_is_clust(plan->index)) {
01042 
01043     plan->must_get_clust = TRUE;
01044 
01045     node->pcur = &(plan->clust_pcur);
01046   } else {
01047     node->pcur = &(plan->pcur);
01048   }
01049 
01050   return(node);
01051 }
01052 
01053 /*********************************************************************/
01056 UNIV_INTERN
01057 ins_node_t*
01058 pars_insert_statement(
01059 /*==================*/
01060   sym_node_t* table_sym,  
01061   que_node_t* values_list,  
01062   sel_node_t* select)   
01063 {
01064   ins_node_t* node;
01065   dtuple_t* row;
01066   ulint   ins_type;
01067 
01068   ut_a(values_list || select);
01069   ut_a(!values_list || !select);
01070 
01071   if (values_list) {
01072     ins_type = INS_VALUES;
01073   } else {
01074     ins_type = INS_SEARCHED;
01075   }
01076 
01077   pars_retrieve_table_def(table_sym);
01078 
01079   node = ins_node_create(ins_type, table_sym->table,
01080              pars_sym_tab_global->heap);
01081 
01082   row = dtuple_create(pars_sym_tab_global->heap,
01083           dict_table_get_n_cols(node->table));
01084 
01085   dict_table_copy_types(row, table_sym->table);
01086 
01087   ins_node_set_new_row(node, row);
01088 
01089   node->select = select;
01090 
01091   if (select) {
01092     select->common.parent = node;
01093 
01094     ut_a(que_node_list_get_len(select->select_list)
01095          == dict_table_get_n_user_cols(table_sym->table));
01096   }
01097 
01098   node->values_list = values_list;
01099 
01100   if (node->values_list) {
01101     pars_resolve_exp_list_variables_and_types(NULL, values_list);
01102 
01103     ut_a(que_node_list_get_len(values_list)
01104          == dict_table_get_n_user_cols(table_sym->table));
01105   }
01106 
01107   return(node);
01108 }
01109 
01110 /*********************************************************************/
01112 static
01113 void
01114 pars_set_dfield_type(
01115 /*=================*/
01116   dfield_t*   dfield,   
01117   pars_res_word_t*  type,   
01119   ulint     len,    
01120   ibool     is_unsigned,  
01122   ibool     is_not_null)  
01124 {
01125   ulint flags = 0;
01126 
01127   if (is_not_null) {
01128     flags |= DATA_NOT_NULL;
01129   }
01130 
01131   if (is_unsigned) {
01132     flags |= DATA_UNSIGNED;
01133   }
01134 
01135   if (type == &pars_int_token) {
01136     ut_a((len == 0) || (len == 8));
01137     if (len == 8) {
01138       dtype_set(dfield_get_type(dfield), DATA_INT, flags, 8);
01139     } else {
01140       dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4);
01141     }
01142 
01143   } else if (type == &pars_char_token) {
01144     ut_a(len == 0);
01145 
01146     dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
01147         DATA_ENGLISH | flags, 0);
01148   } else if (type == &pars_binary_token) {
01149     ut_a(len != 0);
01150 
01151     dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
01152         DATA_BINARY_TYPE | flags, len);
01153   } else if (type == &pars_blob_token) {
01154     ut_a(len == 0);
01155 
01156     dtype_set(dfield_get_type(dfield), DATA_BLOB,
01157         DATA_BINARY_TYPE | flags, 0);
01158   } else {
01159     ut_error;
01160   }
01161 }
01162 
01163 /*********************************************************************/
01166 UNIV_INTERN
01167 sym_node_t*
01168 pars_variable_declaration(
01169 /*======================*/
01170   sym_node_t* node, 
01172   pars_res_word_t* type)  
01173 {
01174   node->resolved = TRUE;
01175   node->token_type = SYM_VAR;
01176 
01177   node->param_type = PARS_NOT_PARAM;
01178 
01179   pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
01180 
01181   return(node);
01182 }
01183 
01184 /*********************************************************************/
01187 UNIV_INTERN
01188 sym_node_t*
01189 pars_parameter_declaration(
01190 /*=======================*/
01191   sym_node_t* node, 
01193   ulint   param_type,
01195   pars_res_word_t* type)  
01196 {
01197   ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
01198 
01199   pars_variable_declaration(node, type);
01200 
01201   node->param_type = param_type;
01202 
01203   return(node);
01204 }
01205 
01206 /*********************************************************************/
01208 static
01209 void
01210 pars_set_parent_in_list(
01211 /*====================*/
01212   que_node_t* node_list,  
01213   que_node_t* parent)   
01215 {
01216   que_common_t* common;
01217 
01218   common = static_cast<que_common_t *>(node_list);
01219 
01220   while (common) {
01221     common->parent = parent;
01222 
01223     common = static_cast<que_common_t *>(que_node_get_next(common));
01224   }
01225 }
01226 
01227 /*********************************************************************/
01230 UNIV_INTERN
01231 elsif_node_t*
01232 pars_elsif_element(
01233 /*===============*/
01234   que_node_t* cond,   
01235   que_node_t* stat_list)  
01236 {
01237   elsif_node_t* node;
01238 
01239   node = static_cast<elsif_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(elsif_node_t)));
01240 
01241   node->common.type = QUE_NODE_ELSIF;
01242 
01243   node->cond = cond;
01244 
01245   pars_resolve_exp_variables_and_types(NULL, cond);
01246 
01247   node->stat_list = stat_list;
01248 
01249   return(node);
01250 }
01251 
01252 /*********************************************************************/
01255 UNIV_INTERN
01256 if_node_t*
01257 pars_if_statement(
01258 /*==============*/
01259   que_node_t* cond,   
01260   que_node_t* stat_list,  
01261   que_node_t* else_part)  
01263 {
01264   if_node_t*  node;
01265   elsif_node_t* elsif_node;
01266 
01267   node = static_cast<if_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(if_node_t)));
01268 
01269   node->common.type = QUE_NODE_IF;
01270 
01271   node->cond = cond;
01272 
01273   pars_resolve_exp_variables_and_types(NULL, cond);
01274 
01275   node->stat_list = stat_list;
01276 
01277   if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) {
01278 
01279     /* There is a list of elsif conditions */
01280 
01281     node->else_part = NULL;
01282     node->elsif_list = static_cast<elsif_node_t *>(else_part);
01283 
01284     elsif_node = static_cast<elsif_node_t *>(else_part);
01285 
01286     while (elsif_node) {
01287       pars_set_parent_in_list(elsif_node->stat_list, node);
01288 
01289       elsif_node = static_cast<elsif_node_t *>(que_node_get_next(elsif_node));
01290     }
01291   } else {
01292     node->else_part = else_part;
01293     node->elsif_list = NULL;
01294 
01295     pars_set_parent_in_list(else_part, node);
01296   }
01297 
01298   pars_set_parent_in_list(stat_list, node);
01299 
01300   return(node);
01301 }
01302 
01303 /*********************************************************************/
01306 UNIV_INTERN
01307 while_node_t*
01308 pars_while_statement(
01309 /*=================*/
01310   que_node_t* cond,   
01311   que_node_t* stat_list)  
01312 {
01313   while_node_t* node;
01314 
01315   node = static_cast<while_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(while_node_t)));
01316 
01317   node->common.type = QUE_NODE_WHILE;
01318 
01319   node->cond = cond;
01320 
01321   pars_resolve_exp_variables_and_types(NULL, cond);
01322 
01323   node->stat_list = stat_list;
01324 
01325   pars_set_parent_in_list(stat_list, node);
01326 
01327   return(node);
01328 }
01329 
01330 /*********************************************************************/
01333 UNIV_INTERN
01334 for_node_t*
01335 pars_for_statement(
01336 /*===============*/
01337   sym_node_t* loop_var, 
01338   que_node_t* loop_start_limit,
01339   que_node_t* loop_end_limit, 
01340   que_node_t* stat_list)  
01341 {
01342   for_node_t* node;
01343 
01344   node = static_cast<for_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t)));
01345 
01346   node->common.type = QUE_NODE_FOR;
01347 
01348   pars_resolve_exp_variables_and_types(NULL, loop_var);
01349   pars_resolve_exp_variables_and_types(NULL, loop_start_limit);
01350   pars_resolve_exp_variables_and_types(NULL, loop_end_limit);
01351 
01352   node->loop_var = loop_var->indirection;
01353 
01354   ut_a(loop_var->indirection);
01355 
01356   node->loop_start_limit = loop_start_limit;
01357   node->loop_end_limit = loop_end_limit;
01358 
01359   node->stat_list = stat_list;
01360 
01361   pars_set_parent_in_list(stat_list, node);
01362 
01363   return(node);
01364 }
01365 
01366 /*********************************************************************/
01369 UNIV_INTERN
01370 exit_node_t*
01371 pars_exit_statement(void)
01372 /*=====================*/
01373 {
01374   exit_node_t*  node;
01375 
01376   node = static_cast<exit_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t)));
01377   node->common.type = QUE_NODE_EXIT;
01378 
01379   return(node);
01380 }
01381 
01382 /*********************************************************************/
01385 UNIV_INTERN
01386 return_node_t*
01387 pars_return_statement(void)
01388 /*=======================*/
01389 {
01390   return_node_t*  node;
01391 
01392   node = static_cast<return_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
01393             sizeof(return_node_t)));
01394   node->common.type = QUE_NODE_RETURN;
01395 
01396   return(node);
01397 }
01398 
01399 /*********************************************************************/
01402 UNIV_INTERN
01403 assign_node_t*
01404 pars_assignment_statement(
01405 /*======================*/
01406   sym_node_t* var,  
01407   que_node_t* val)  
01408 {
01409   assign_node_t*  node;
01410 
01411   node = static_cast<assign_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
01412             sizeof(assign_node_t)));
01413   node->common.type = QUE_NODE_ASSIGNMENT;
01414 
01415   node->var = var;
01416   node->val = val;
01417 
01418   pars_resolve_exp_variables_and_types(NULL, var);
01419   pars_resolve_exp_variables_and_types(NULL, val);
01420 
01421   ut_a(dtype_get_mtype(dfield_get_type(que_node_get_val(var)))
01422        == dtype_get_mtype(dfield_get_type(que_node_get_val(val))));
01423 
01424   return(node);
01425 }
01426 
01427 /*********************************************************************/
01430 UNIV_INTERN
01431 func_node_t*
01432 pars_procedure_call(
01433 /*================*/
01434   que_node_t* res_word,
01435   que_node_t* args) 
01436 {
01437   func_node_t*  node;
01438 
01439   node = pars_func(res_word, args);
01440 
01441   pars_resolve_exp_list_variables_and_types(NULL, args);
01442 
01443   return(node);
01444 }
01445 
01446 /*********************************************************************/
01450 UNIV_INTERN
01451 fetch_node_t*
01452 pars_fetch_statement(
01453 /*=================*/
01454   sym_node_t* cursor,   
01455   sym_node_t* into_list,  
01456   sym_node_t* user_func)  
01457 {
01458   sym_node_t* cursor_decl;
01459   fetch_node_t* node;
01460 
01461   /* Logical XOR. */
01462   ut_a(!into_list != !user_func);
01463 
01464   node = static_cast<fetch_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t)));
01465 
01466   node->common.type = QUE_NODE_FETCH;
01467 
01468   pars_resolve_exp_variables_and_types(NULL, cursor);
01469 
01470   if (into_list) {
01471     pars_resolve_exp_list_variables_and_types(NULL, into_list);
01472     node->into_list = into_list;
01473     node->func = NULL;
01474   } else {
01475     pars_resolve_exp_variables_and_types(NULL, user_func);
01476 
01477     node->func = pars_info_get_user_func(pars_sym_tab_global->info,
01478                  user_func->name);
01479     ut_a(node->func);
01480 
01481     node->into_list = NULL;
01482   }
01483 
01484   cursor_decl = cursor->alias;
01485 
01486   ut_a(cursor_decl->token_type == SYM_CURSOR);
01487 
01488   node->cursor_def = cursor_decl->cursor_def;
01489 
01490   if (into_list) {
01491     ut_a(que_node_list_get_len(into_list)
01492          == que_node_list_get_len(node->cursor_def->select_list));
01493   }
01494 
01495   return(node);
01496 }
01497 
01498 /*********************************************************************/
01501 UNIV_INTERN
01502 open_node_t*
01503 pars_open_statement(
01504 /*================*/
01505   ulint   type, 
01507   sym_node_t* cursor) 
01508 {
01509   sym_node_t* cursor_decl;
01510   open_node_t*  node;
01511 
01512   node = static_cast<open_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(open_node_t)));
01513 
01514   node->common.type = QUE_NODE_OPEN;
01515 
01516   pars_resolve_exp_variables_and_types(NULL, cursor);
01517 
01518   cursor_decl = cursor->alias;
01519 
01520   ut_a(cursor_decl->token_type == SYM_CURSOR);
01521 
01522   node->op_type = static_cast<open_node_op>(type);
01523   node->cursor_def = cursor_decl->cursor_def;
01524 
01525   return(node);
01526 }
01527 
01528 /*********************************************************************/
01531 UNIV_INTERN
01532 row_printf_node_t*
01533 pars_row_printf_statement(
01534 /*======================*/
01535   sel_node_t* sel_node) 
01536 {
01537   row_printf_node_t*  node;
01538 
01539   node = static_cast<row_printf_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
01540             sizeof(row_printf_node_t)));
01541   node->common.type = QUE_NODE_ROW_PRINTF;
01542 
01543   node->sel_node = sel_node;
01544 
01545   sel_node->common.parent = node;
01546 
01547   return(node);
01548 }
01549 
01550 /*********************************************************************/
01553 UNIV_INTERN
01554 commit_node_t*
01555 pars_commit_statement(void)
01556 /*=======================*/
01557 {
01558   return(commit_node_create(pars_sym_tab_global->heap));
01559 }
01560 
01561 /*********************************************************************/
01564 UNIV_INTERN
01565 roll_node_t*
01566 pars_rollback_statement(void)
01567 /*=========================*/
01568 {
01569   return(roll_node_create(pars_sym_tab_global->heap));
01570 }
01571 
01572 /*********************************************************************/
01575 UNIV_INTERN
01576 sym_node_t*
01577 pars_column_def(
01578 /*============*/
01579   sym_node_t*   sym_node, 
01581   pars_res_word_t*  type,   
01582   sym_node_t*   len,    
01584   void*     is_unsigned,  
01586   void*     is_not_null)  
01588 {
01589   ulint len2;
01590 
01591   if (len) {
01592     len2 = eval_node_get_int_val(len);
01593   } else {
01594     len2 = 0;
01595   }
01596 
01597   pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
01598            is_unsigned != NULL, is_not_null != NULL);
01599 
01600   return(sym_node);
01601 }
01602 
01603 /*********************************************************************/
01606 UNIV_INTERN
01607 tab_node_t*
01608 pars_create_table(
01609 /*==============*/
01610   sym_node_t* table_sym,  
01612   sym_node_t* column_defs,  
01613   void*   /*not_fit_in_memory __attribute__((unused))*/)
01624 {
01625   dict_table_t* table;
01626   sym_node_t* column;
01627   tab_node_t* node;
01628   const dtype_t*  dtype;
01629   ulint   n_cols;
01630 
01631   n_cols = que_node_list_get_len(column_defs);
01632 
01633   /* As the InnoDB SQL parser is for internal use only,
01634   for creating some system tables, this function will only
01635   create tables in the old (not compact) record format. */
01636   table = dict_mem_table_create(table_sym->name, 0, n_cols, 0);
01637 
01638 #ifdef UNIV_DEBUG
01639   if (not_fit_in_memory != NULL) {
01640     table->does_not_fit_in_memory = TRUE;
01641   }
01642 #endif /* UNIV_DEBUG */
01643   column = column_defs;
01644 
01645   while (column) {
01646     dtype = dfield_get_type(que_node_get_val(column));
01647 
01648     dict_mem_table_add_col(table, table->heap,
01649                column->name, dtype->mtype,
01650                dtype->prtype, dtype->len);
01651     column->resolved = TRUE;
01652     column->token_type = SYM_COLUMN;
01653 
01654     column = static_cast<sym_node_t *>(que_node_get_next(column));
01655   }
01656 
01657   node = tab_create_graph_create(table, pars_sym_tab_global->heap);
01658 
01659   table_sym->resolved = TRUE;
01660   table_sym->token_type = SYM_TABLE;
01661 
01662   return(node);
01663 }
01664 
01665 /*********************************************************************/
01668 UNIV_INTERN
01669 ind_node_t*
01670 pars_create_index(
01671 /*==============*/
01672   pars_res_word_t* unique_def,  
01673   pars_res_word_t* clustered_def, 
01674   sym_node_t* index_sym,  
01676   sym_node_t* table_sym,  
01678   sym_node_t* column_list)  
01679 {
01680   dict_index_t* index;
01681   sym_node_t* column;
01682   ind_node_t* node;
01683   ulint   n_fields;
01684   ulint   ind_type;
01685 
01686   n_fields = que_node_list_get_len(column_list);
01687 
01688   ind_type = 0;
01689 
01690   if (unique_def) {
01691     ind_type = ind_type | DICT_UNIQUE;
01692   }
01693 
01694   if (clustered_def) {
01695     ind_type = ind_type | DICT_CLUSTERED;
01696   }
01697 
01698   index = dict_mem_index_create(table_sym->name, index_sym->name, 0,
01699               ind_type, n_fields);
01700   column = column_list;
01701 
01702   while (column) {
01703     dict_mem_index_add_field(index, column->name, 0);
01704 
01705     column->resolved = TRUE;
01706     column->token_type = SYM_COLUMN;
01707 
01708     column = static_cast<sym_node_t *>(que_node_get_next(column));
01709   }
01710 
01711   node = ind_create_graph_create(index, pars_sym_tab_global->heap);
01712 
01713   table_sym->resolved = TRUE;
01714   table_sym->token_type = SYM_TABLE;
01715 
01716   index_sym->resolved = TRUE;
01717   index_sym->token_type = SYM_TABLE;
01718 
01719   return(node);
01720 }
01721 
01722 /*********************************************************************/
01725 UNIV_INTERN
01726 que_fork_t*
01727 pars_procedure_definition(
01728 /*======================*/
01729   sym_node_t* sym_node, 
01731   sym_node_t* param_list, 
01732   que_node_t* stat_list)  
01733 {
01734   proc_node_t*  node;
01735   que_fork_t* fork;
01736   que_thr_t*  thr;
01737   mem_heap_t* heap;
01738 
01739   heap = pars_sym_tab_global->heap;
01740 
01741   fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap);
01742   fork->trx = NULL;
01743 
01744   thr = que_thr_create(fork, heap);
01745 
01746   node = static_cast<proc_node_t *>(mem_heap_alloc(heap, sizeof(proc_node_t)));
01747 
01748   node->common.type = QUE_NODE_PROC;
01749   node->common.parent = thr;
01750 
01751   sym_node->token_type = SYM_PROCEDURE_NAME;
01752   sym_node->resolved = TRUE;
01753 
01754   node->proc_id = sym_node;
01755   node->param_list = param_list;
01756   node->stat_list = stat_list;
01757 
01758   pars_set_parent_in_list(stat_list, node);
01759 
01760   node->sym_tab = pars_sym_tab_global;
01761 
01762   thr->child = node;
01763 
01764   pars_sym_tab_global->query_graph = fork;
01765 
01766   return(fork);
01767 }
01768 
01769 /*************************************************************/
01775 UNIV_INTERN
01776 que_fork_t*
01777 pars_stored_procedure_call(
01778 /*=======================*/
01779   sym_node_t* /*sym_node __attribute__((unused))*/)
01781 {
01782   ut_error;
01783   return(NULL);
01784 }
01785 
01786 /*************************************************************/
01788 #ifdef __cplusplus
01789 extern "C"
01790 #endif
01791 UNIV_INTERN
01792 void
01793 pars_get_lex_chars(
01794 /*===============*/
01795   char* buf,    
01796   int*  result,   
01797   int max_size) 
01799 {
01800   int len;
01801 
01802   len = pars_sym_tab_global->string_len
01803     - pars_sym_tab_global->next_char_pos;
01804   if (len == 0) {
01805 #ifdef YYDEBUG
01806     /* fputs("SQL string ends\n", stderr); */
01807 #endif
01808     *result = 0;
01809 
01810     return;
01811   }
01812 
01813   if (len > max_size) {
01814     len = max_size;
01815   }
01816 
01817 #ifdef UNIV_SQL_DEBUG
01818   if (pars_print_lexed) {
01819 
01820     if (len >= 5) {
01821       len = 5;
01822     }
01823 
01824     fwrite(pars_sym_tab_global->sql_string
01825            + pars_sym_tab_global->next_char_pos,
01826            1, len, stderr);
01827   }
01828 #endif /* UNIV_SQL_DEBUG */
01829 
01830   ut_memcpy(buf, pars_sym_tab_global->sql_string
01831       + pars_sym_tab_global->next_char_pos, len);
01832   *result = len;
01833 
01834   pars_sym_tab_global->next_char_pos += len;
01835 }
01836 
01837 /*************************************************************/
01839 UNIV_INTERN
01840 void
01841 yyerror(
01842 /*====*/
01843   const char* /*s __attribute__((unused))*/)
01845 {
01846   ut_ad(s);
01847 
01848   fputs("PARSER ERROR: Syntax error in SQL string\n", stderr);
01849 
01850   ut_error;
01851 }
01852 
01853 /*************************************************************/
01856 UNIV_INTERN
01857 que_t*
01858 pars_sql(
01859 /*=====*/
01860   pars_info_t*  info, 
01861   const char* str)  
01862 {
01863   sym_node_t* sym_node;
01864   mem_heap_t* heap;
01865   que_t*    graph;
01866 
01867   ut_ad(str);
01868 
01869   heap = mem_heap_create(256);
01870 
01871   /* Currently, the parser is not reentrant: */
01872   ut_ad(mutex_own(&(dict_sys->mutex)));
01873 
01874   pars_sym_tab_global = sym_tab_create(heap);
01875 
01876   pars_sym_tab_global->string_len = strlen(str);
01877   pars_sym_tab_global->sql_string = static_cast<const char *>(mem_heap_dup(
01878     heap, str, pars_sym_tab_global->string_len + 1));
01879   pars_sym_tab_global->next_char_pos = 0;
01880   pars_sym_tab_global->info = info;
01881 
01882   yyparse();
01883 
01884   sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
01885 
01886   while (sym_node) {
01887     ut_a(sym_node->resolved);
01888 
01889     sym_node = UT_LIST_GET_NEXT(sym_list, sym_node);
01890   }
01891 
01892   graph = pars_sym_tab_global->query_graph;
01893 
01894   graph->sym_tab = pars_sym_tab_global;
01895   graph->info = info;
01896 
01897   /* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
01898 
01899   return(graph);
01900 }
01901 
01902 /******************************************************************/
01907 UNIV_INTERN
01908 que_thr_t*
01909 pars_complete_graph_for_exec(
01910 /*=========================*/
01911   que_node_t* node, 
01913   trx_t*    trx,  
01914   mem_heap_t* heap) 
01915 {
01916   que_fork_t* fork;
01917   que_thr_t*  thr;
01918 
01919   fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap);
01920   fork->trx = trx;
01921 
01922   thr = que_thr_create(fork, heap);
01923 
01924   thr->child = node;
01925 
01926   que_node_set_parent(node, thr);
01927 
01928   trx->graph = NULL;
01929 
01930   return(thr);
01931 }
01932 
01933 /****************************************************************/
01936 UNIV_INTERN
01937 pars_info_t*
01938 pars_info_create(void)
01939 /*==================*/
01940 {
01941   pars_info_t*  info;
01942   mem_heap_t* heap;
01943 
01944   heap = mem_heap_create(512);
01945 
01946   info = static_cast<pars_info_t *>(mem_heap_alloc(heap, sizeof(*info)));
01947 
01948   info->heap = heap;
01949   info->funcs = NULL;
01950   info->bound_lits = NULL;
01951   info->bound_ids = NULL;
01952   info->graph_owns_us = TRUE;
01953 
01954   return(info);
01955 }
01956 
01957 /****************************************************************/
01959 UNIV_INTERN
01960 void
01961 pars_info_free(
01962 /*===========*/
01963   pars_info_t*  info) 
01964 {
01965   mem_heap_free(info->heap);
01966 }
01967 
01968 /****************************************************************/
01970 UNIV_INTERN
01971 void
01972 pars_info_add_literal(
01973 /*==================*/
01974   pars_info_t*  info,   
01975   const char* name,   
01976   const void* address,  
01977   ulint   length,   
01978   ulint   type,   
01979   ulint   prtype)   
01981 {
01982   pars_bound_lit_t* pbl;
01983 
01984   ut_ad(!pars_info_get_bound_lit(info, name));
01985 
01986   pbl = static_cast<pars_bound_lit_t *>(mem_heap_alloc(info->heap, sizeof(*pbl)));
01987 
01988   pbl->name = name;
01989   pbl->address = address;
01990   pbl->length = length;
01991   pbl->type = type;
01992   pbl->prtype = prtype;
01993 
01994   if (!info->bound_lits) {
01995     info->bound_lits = ib_vector_create(info->heap, 8);
01996   }
01997 
01998   ib_vector_push(info->bound_lits, pbl);
01999 }
02000 
02001 /****************************************************************/
02004 UNIV_INTERN
02005 void
02006 pars_info_add_str_literal(
02007 /*======================*/
02008   pars_info_t*  info,   
02009   const char* name,   
02010   const char* str)    
02011 {
02012   pars_info_add_literal(info, name, str, strlen(str),
02013             DATA_VARCHAR, DATA_ENGLISH);
02014 }
02015 
02016 /****************************************************************/
02025 UNIV_INTERN
02026 void
02027 pars_info_add_int4_literal(
02028 /*=======================*/
02029   pars_info_t*  info,   
02030   const char* name,   
02031   lint    val)    
02032 {
02033   byte* buf = static_cast<byte *>(mem_heap_alloc(info->heap, 4));
02034 
02035   mach_write_to_4(buf, val);
02036   pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
02037 }
02038 
02039 /****************************************************************/
02048 UNIV_INTERN
02049 void
02050 pars_info_add_ull_literal(
02051 /*======================*/
02052   pars_info_t*  info,   
02053   const char* name,   
02054   ib_uint64_t val)    
02055 {
02056   byte* buf = static_cast<byte *>(mem_heap_alloc(info->heap, 8));
02057 
02058   mach_write_to_8(buf, val);
02059 
02060   pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
02061 }
02062 
02063 /****************************************************************/
02065 UNIV_INTERN
02066 void
02067 pars_info_add_function(
02068 /*===================*/
02069   pars_info_t*    info, 
02070   const char*   name, 
02071   pars_user_func_cb_t func, 
02072   void*     arg)  
02073 {
02074   pars_user_func_t* puf;
02075 
02076   ut_ad(!pars_info_get_user_func(info, name));
02077 
02078   puf = static_cast<pars_user_func_t *>(mem_heap_alloc(info->heap, sizeof(*puf)));
02079 
02080   puf->name = name;
02081   puf->func = func;
02082   puf->arg = arg;
02083 
02084   if (!info->funcs) {
02085     info->funcs = ib_vector_create(info->heap, 8);
02086   }
02087 
02088   ib_vector_push(info->funcs, puf);
02089 }
02090 
02091 /****************************************************************/
02093 UNIV_INTERN
02094 void
02095 pars_info_add_id(
02096 /*=============*/
02097   pars_info_t*  info,   
02098   const char* name,   
02099   const char* id)   
02100 {
02101   pars_bound_id_t*  bid;
02102 
02103   ut_ad(!pars_info_get_bound_id(info, name));
02104 
02105   bid = static_cast<pars_bound_id_t *>(mem_heap_alloc(info->heap, sizeof(*bid)));
02106 
02107   bid->name = name;
02108   bid->id = id;
02109 
02110   if (!info->bound_ids) {
02111     info->bound_ids = ib_vector_create(info->heap, 8);
02112   }
02113 
02114   ib_vector_push(info->bound_ids, bid);
02115 }
02116 
02117 /****************************************************************/
02120 UNIV_INTERN
02121 pars_user_func_t*
02122 pars_info_get_user_func(
02123 /*====================*/
02124   pars_info_t*    info, 
02125   const char*   name) 
02126 {
02127   ulint   i;
02128   ib_vector_t*  vec;
02129 
02130   if (!info || !info->funcs) {
02131     return(NULL);
02132   }
02133 
02134   vec = info->funcs;
02135 
02136   for (i = 0; i < ib_vector_size(vec); i++) {
02137     pars_user_func_t* puf = static_cast<pars_user_func_t *>(ib_vector_get(vec, i));
02138 
02139     if (strcmp(puf->name, name) == 0) {
02140       return(puf);
02141     }
02142   }
02143 
02144   return(NULL);
02145 }
02146 
02147 /****************************************************************/
02150 UNIV_INTERN
02151 pars_bound_lit_t*
02152 pars_info_get_bound_lit(
02153 /*====================*/
02154   pars_info_t*    info, 
02155   const char*   name) 
02156 {
02157   ulint   i;
02158   ib_vector_t*  vec;
02159 
02160   if (!info || !info->bound_lits) {
02161     return(NULL);
02162   }
02163 
02164   vec = info->bound_lits;
02165 
02166   for (i = 0; i < ib_vector_size(vec); i++) {
02167     pars_bound_lit_t* pbl = static_cast<pars_bound_lit_t *>(ib_vector_get(vec, i));
02168 
02169     if (strcmp(pbl->name, name) == 0) {
02170       return(pbl);
02171     }
02172   }
02173 
02174   return(NULL);
02175 }
02176 
02177 /****************************************************************/
02180 UNIV_INTERN
02181 pars_bound_id_t*
02182 pars_info_get_bound_id(
02183 /*===================*/
02184   pars_info_t*    info, 
02185   const char*   name) 
02186 {
02187   ulint   i;
02188   ib_vector_t*  vec;
02189 
02190   if (!info || !info->bound_ids) {
02191     return(NULL);
02192   }
02193 
02194   vec = info->bound_ids;
02195 
02196   for (i = 0; i < ib_vector_size(vec); i++) {
02197     pars_bound_id_t*  bid = static_cast<pars_bound_id_t *>(ib_vector_get(vec, i));
02198 
02199     if (strcmp(bid->name, name) == 0) {
02200       return(bid);
02201     }
02202   }
02203 
02204   return(NULL);
02205 }