diff options
Diffstat (limited to 'storage/innobase')
68 files changed, 4179 insertions, 2961 deletions
diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 22796b45882..dfc3a511d52 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -76,8 +76,7 @@ EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr include/univ.i include/usr0sess.h include/usr0sess.ic include/usr0types.h \ include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \ include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \ - include/ut0sort.h include/ut0ut.h include/ut0ut.ic \ - cmakelists.txt + include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 4ece0e36b19..5e338f97982 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -144,7 +144,7 @@ btr_root_get( root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr); ut_a((ibool)!!page_is_comp(root) == - dict_table_is_comp(UT_LIST_GET_FIRST(tree->tree_indexes)->table)); + dict_table_is_comp(tree->tree_index->table)); return(root); } @@ -259,7 +259,7 @@ btr_page_create( ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); page_create(page, mtr, - dict_table_is_comp(UT_LIST_GET_FIRST(tree->tree_indexes)->table)); + dict_table_is_comp(tree->tree_index->table)); buf_block_align(page)->check_index_page_at_flush = TRUE; btr_page_set_index_id(page, tree->id, mtr); @@ -574,7 +574,7 @@ btr_page_get_father_for_rec( tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap, btr_page_get_level(page, mtr)); - index = UT_LIST_GET_FIRST(tree->tree_indexes); + index = tree->tree_index; /* In the following, we choose just any index from the tree as the first parameter for btr_cur_search_to_nth_level. */ @@ -1073,8 +1073,7 @@ btr_root_raise_and_insert( /* fprintf(stderr, "Root raise new page no %lu\n", buf_frame_get_page_no(new_page)); */ - ibuf_reset_free_bits(UT_LIST_GET_FIRST(tree->tree_indexes), - new_page); + ibuf_reset_free_bits(tree->tree_index, new_page); /* Reposition the cursor to the child node */ page_cur_search(new_page, cursor->index, tuple, PAGE_CUR_LE, page_cursor); @@ -1415,7 +1414,7 @@ btr_insert_on_non_leaf_level( /* In the following, choose just any index from the tree as the first parameter for btr_cur_search_to_nth_level. */ - btr_cur_search_to_nth_level(UT_LIST_GET_FIRST(tree->tree_indexes), + btr_cur_search_to_nth_level(tree->tree_index, level, tuple, PAGE_CUR_LE, BTR_CONT_MODIFY_TREE, &cursor, 0, mtr); @@ -1479,7 +1478,7 @@ btr_attach_half_pages( btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets(node_ptr, - UT_LIST_GET_FIRST(tree->tree_indexes), + tree->tree_index, NULL, ULINT_UNDEFINED, &heap), lower_page_no, mtr); mem_heap_empty(heap); @@ -1768,8 +1767,8 @@ func_start: buf_frame_get_page_no(left_page), buf_frame_get_page_no(right_page)); */ - ut_ad(page_validate(left_page, UT_LIST_GET_FIRST(tree->tree_indexes))); - ut_ad(page_validate(right_page, UT_LIST_GET_FIRST(tree->tree_indexes))); + ut_ad(page_validate(left_page, tree->tree_index)); + ut_ad(page_validate(right_page, tree->tree_index)); mem_heap_free(heap); return(rec); @@ -1910,8 +1909,7 @@ btr_node_ptr_delete( node_ptr = btr_page_get_father_node_ptr(tree, page, mtr); - btr_cur_position(UT_LIST_GET_FIRST(tree->tree_indexes), node_ptr, - &cursor); + btr_cur_position(tree->tree_index, node_ptr, &cursor); compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, FALSE, mtr); ut_a(err == DB_SUCCESS); @@ -1947,7 +1945,7 @@ btr_lift_page_up( btr_page_get_father_node_ptr(tree, page, mtr)); page_level = btr_page_get_level(page, mtr); - index = UT_LIST_GET_FIRST(tree->tree_indexes); + index = tree->tree_index; btr_search_drop_page_hash_index(page); @@ -2180,8 +2178,7 @@ btr_discard_only_page_on_level( btr_page_empty(father_page, mtr); /* We play safe and reset the free bits for the father */ - ibuf_reset_free_bits(UT_LIST_GET_FIRST(tree->tree_indexes), - father_page); + ibuf_reset_free_bits(tree->tree_index, father_page); } else { ut_ad(page_get_n_recs(father_page) == 1); @@ -2449,7 +2446,7 @@ btr_check_node_ptr( ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr, rec_get_offsets(node_ptr, - dict_tree_find_index(tree, node_ptr), + tree->tree_index, NULL, ULINT_UNDEFINED, &heap)) == 0); mem_heap_free(heap); @@ -2692,7 +2689,7 @@ btr_validate_level( space = buf_frame_get_space_id(page); - index = UT_LIST_GET_FIRST(tree->tree_indexes); + index = tree->tree_index; while (level != btr_page_get_level(page, &mtr)) { diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 14e991bb3c6..deba3e23487 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -1606,7 +1606,7 @@ btr_cur_optimistic_update( new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update, - NULL); + FALSE, NULL); old_rec_size = rec_offs_size(offsets); new_rec_size = rec_get_converted_size(index, new_entry); @@ -1846,7 +1846,7 @@ btr_cur_pessimistic_update( new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update, - heap); + FALSE, heap); if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR, roll_ptr); @@ -1915,13 +1915,13 @@ btr_cur_pessimistic_update( ut_a(rec || optim_err != DB_UNDERFLOW); if (rec) { - offsets = rec_get_offsets(rec, index, offsets, - ULINT_UNDEFINED, &heap); - lock_rec_restore_from_page_infimum(rec, page); rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); + if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { /* The new inserted record owns its possible externally stored fields */ @@ -2371,8 +2371,7 @@ btr_cur_compress( ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(btr_cur_get_tree(cursor)), MTR_MEMO_X_LOCK)); - ut_ad(mtr_memo_contains(mtr, buf_block_align( - btr_cur_get_page(cursor)), + ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)), MTR_MEMO_PAGE_X_FIX)); ut_ad(btr_page_get_level(btr_cur_get_page(cursor), mtr) == 0); @@ -2398,8 +2397,7 @@ btr_cur_compress_if_useful( ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(btr_cur_get_tree(cursor)), MTR_MEMO_X_LOCK)); - ut_ad(mtr_memo_contains(mtr, buf_block_align( - btr_cur_get_page(cursor)), + ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)), MTR_MEMO_PAGE_X_FIX)); if (btr_cur_compress_recommendation(cursor, mtr)) { @@ -2437,7 +2435,7 @@ btr_cur_optimistic_delete( ibool no_compress_needed; *offsets_ = (sizeof offsets_) / sizeof *offsets_; - ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)), + ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)), MTR_MEMO_PAGE_X_FIX)); /* This is intended only for leaf page deletions */ @@ -3330,7 +3328,10 @@ btr_store_big_rec_extern_fields( dict_index_t* index, /* in: index of rec; the index tree MUST be X-latched */ rec_t* rec, /* in: record */ - const ulint* offsets, /* in: rec_get_offsets(rec, index) */ + const ulint* offsets, /* in: rec_get_offsets(rec, index); + the "external storage" flags in offsets + will not correspond to rec when + this function returns */ big_rec_t* big_rec_vec, /* in: vector containing fields to be stored externally */ mtr_t* local_mtr __attribute__((unused))) /* in: mtr diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index e3ba50a2d5b..85a6577bafb 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -259,10 +259,7 @@ btr_pcur_restore_position( cursor->latch_mode = latch_mode; #ifdef UNIV_DEBUG rec = btr_pcur_get_rec(cursor); - index = dict_tree_find_index( - btr_cur_get_tree( - btr_pcur_get_btr_cur(cursor)), - rec); + index = btr_pcur_get_btr_cur(cursor)->index; heap = mem_heap_create(256); offsets1 = rec_get_offsets(cursor->old_rec, diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c index 428b4d9a6b7..be7bb7c421f 100644 --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -24,8 +24,8 @@ ulint btr_search_this_is_zero = 0; /* A dummy variable to fool the #ifdef UNIV_SEARCH_PERF_STAT ulint btr_search_n_succ = 0; -#endif /* UNIV_SEARCH_PERF_STAT */ ulint btr_search_n_hash_fail = 0; +#endif /* UNIV_SEARCH_PERF_STAT */ byte btr_sea_pad1[64]; /* padding to prevent other memory update hotspots from residing on the same memory @@ -59,9 +59,6 @@ before hash index building is started */ #define BTR_SEARCH_BUILD_LIMIT 100 -/* How many cells to check before temporarily releasing btr_search_latch */ -#define BTR_CHUNK_SIZE 10000 - /************************************************************************ Builds a hash index on a page with the given parameters. If the page already has a hash index with different parameters, the old hash index is removed. @@ -172,10 +169,12 @@ btr_search_info_create( info->last_hash_succ = FALSE; +#ifdef UNIV_SEARCH_PERF_STAT info->n_hash_succ = 0; info->n_hash_fail = 0; info->n_patt_succ = 0; info->n_searches = 0; +#endif /* UNIV_SEARCH_PERF_STAT */ /* Set some sensible values */ info->n_fields = 1; @@ -487,7 +486,9 @@ btr_search_info_update_slow( if (cursor->flag == BTR_CUR_HASH_FAIL) { /* Update the hash node reference, if appropriate */ +#ifdef UNIV_SEARCH_PERF_STAT btr_search_n_hash_fail++; +#endif /* UNIV_SEARCH_PERF_STAT */ rw_lock_x_lock(&btr_search_latch); @@ -872,11 +873,11 @@ failure_unlock: rw_lock_s_unlock(&btr_search_latch); } failure: - info->n_hash_fail++; - cursor->flag = BTR_CUR_HASH_FAIL; #ifdef UNIV_SEARCH_PERF_STAT + info->n_hash_fail++; + if (info->n_hash_succ > 0) { info->n_hash_succ--; } @@ -1607,21 +1608,26 @@ btr_search_validate(void) mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; + + /* How many cells to check before temporarily releasing + btr_search_latch. */ + ulint chunk_size = 10000; + *offsets_ = (sizeof offsets_) / sizeof *offsets_; rw_lock_x_lock(&btr_search_latch); cell_count = hash_get_n_cells(btr_search_sys->hash_index); - + for (i = 0; i < cell_count; i++) { /* We release btr_search_latch every once in a while to give other queries a chance to run. */ - if ((i != 0) && ((i % BTR_CHUNK_SIZE) == 0)) { + if ((i != 0) && ((i % chunk_size) == 0)) { rw_lock_x_unlock(&btr_search_latch); os_thread_yield(); rw_lock_x_lock(&btr_search_latch); } - + node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; while (node != NULL) { @@ -1675,9 +1681,9 @@ btr_search_validate(void) } } - for (i = 0; i < cell_count; i += BTR_CHUNK_SIZE) { - ulint end_index = ut_min(i + BTR_CHUNK_SIZE - 1, cell_count - 1); - + for (i = 0; i < cell_count; i += chunk_size) { + ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1); + /* We release btr_search_latch every once in a while to give other queries a chance to run. */ if (i != 0) { diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index 3b6c47a21e9..08be5811a4b 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -294,14 +294,14 @@ buf_LRU_try_free_flushed_blocks(void) } /********************************************************************** -Returns TRUE if less than 15 % of the buffer pool is available. This can be +Returns TRUE if less than 25 % of the buffer pool is available. This can be used in heuristics to prevent huge transactions eating up the whole buffer pool for their locks. */ ibool buf_LRU_buf_pool_running_out(void) /*==============================*/ - /* out: TRUE if less than 15 % of buffer pool + /* out: TRUE if less than 25 % of buffer pool left */ { ibool ret = FALSE; @@ -309,7 +309,7 @@ buf_LRU_buf_pool_running_out(void) mutex_enter(&(buf_pool->mutex)); if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) - + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) { + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) { ret = TRUE; } @@ -340,11 +340,11 @@ loop: mutex_enter(&(buf_pool->mutex)); if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) - + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 10) { + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 20) { ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: ERROR: over 9 / 10 of the buffer pool is occupied by\n" +" InnoDB: ERROR: over 95 percent of the buffer pool is occupied by\n" "InnoDB: lock heaps or the adaptive hash index! Check that your\n" "InnoDB: transactions do not set too many row locks.\n" "InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n" @@ -356,17 +356,17 @@ loop: ut_error; } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) - + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) { + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 3) { if (!buf_lru_switched_on_innodb_mon) { - /* Over 80 % of the buffer pool is occupied by lock + /* Over 67 % of the buffer pool is occupied by lock heaps or the adaptive hash index. This may be a memory leak! */ ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: WARNING: over 4 / 5 of the buffer pool is occupied by\n" +" InnoDB: WARNING: over 67 percent of the buffer pool is occupied by\n" "InnoDB: lock heaps or the adaptive hash index! Check that your\n" "InnoDB: transactions do not set too many row locks.\n" "InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n" @@ -881,10 +881,10 @@ buf_LRU_block_remove_hashed_page( if (buf_page_hash_get(block->space, block->offset)) { fprintf(stderr, "InnoDB: From hash table we find block %p of %lu %lu which is not %p\n", - buf_page_hash_get(block->space, block->offset), + (void*) buf_page_hash_get(block->space, block->offset), (ulong) buf_page_hash_get(block->space, block->offset)->space, (ulong) buf_page_hash_get(block->space, block->offset)->offset, - block); + (void*) block); } #ifdef UNIV_DEBUG diff --git a/storage/innobase/cmakelists.txt b/storage/innobase/cmakelists.txt index de46430e2ab..def51873725 100644 --- a/storage/innobase/cmakelists.txt +++ b/storage/innobase/cmakelists.txt @@ -32,4 +32,4 @@ ADD_LIBRARY(innobase btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c thr/thr0loc.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c usr/usr0sess.c - ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c) + ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c) diff --git a/storage/innobase/configure.in b/storage/innobase/configure.in index e0521471c2f..91afcc1c9b3 100644 --- a/storage/innobase/configure.in +++ b/storage/innobase/configure.in @@ -89,6 +89,25 @@ else CXXFLAGS="$OPTIMIZE_CXXFLAGS -DDBUG_OFF $CXXFLAGS -DDEBUG_OFF" fi +# NOTE: The flags below are disabled by default since we can't easily get +# rid of the "string over 509 characters in length" warnings, and thus can't +# add -Werror. But it's a good idea to enable these for a test compile +# before shipping a new snapshot to MySQL to catch errors that could make +# the compile fail on non-C99 compilers. + +# If using gcc, disallow usage of C99 features to avoid accidentally +# introducing problems on compilers that only implement C89. +#if test "$ac_cv_prog_gcc" = "yes" +#then +# CFLAGS="$CFLAGS -std=c89 -ansi -pedantic -Wno-long-long" +#fi + +# If using gcc, add some extra warning flags. +if test "$ac_cv_prog_gcc" = "yes" +then + CFLAGS="$CFLAGS -Werror-implicit-function-declaration" +fi + case "$target_os" in lin*) CFLAGS="$CFLAGS -DUNIV_LINUX";; diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c index 3ac1139d952..2f36e7250fc 100644 --- a/storage/innobase/data/data0type.c +++ b/storage/innobase/data/data0type.c @@ -216,20 +216,43 @@ dtype_print( mtype = type->mtype; prtype = type->prtype; - if (mtype == DATA_VARCHAR) { + + switch (mtype) { + case DATA_VARCHAR: fputs("DATA_VARCHAR", stderr); - } else if (mtype == DATA_CHAR) { + break; + + case DATA_CHAR: fputs("DATA_CHAR", stderr); - } else if (mtype == DATA_BINARY) { + break; + + case DATA_BINARY: fputs("DATA_BINARY", stderr); - } else if (mtype == DATA_INT) { + break; + + case DATA_FIXBINARY: + fputs("DATA_FIXBINARY", stderr); + break; + + case DATA_BLOB: + fputs("DATA_BLOB", stderr); + break; + + case DATA_INT: fputs("DATA_INT", stderr); - } else if (mtype == DATA_MYSQL) { + break; + + case DATA_MYSQL: fputs("DATA_MYSQL", stderr); - } else if (mtype == DATA_SYS) { + break; + + case DATA_SYS: fputs("DATA_SYS", stderr); - } else { + break; + + default: fprintf(stderr, "type %lu", (ulong) mtype); + break; } len = type->len; @@ -254,6 +277,18 @@ dtype_print( } else { fprintf(stderr, "prtype %lu", (ulong) prtype); } + } else { + if (prtype & DATA_UNSIGNED) { + fputs(" DATA_UNSIGNED", stderr); + } + + if (prtype & DATA_BINARY_TYPE) { + fputs(" DATA_BINARY_TYPE", stderr); + } + + if (prtype & DATA_NOT_NULL) { + fputs(" DATA_NOT_NULL", stderr); + } } fprintf(stderr, " len %lu prec %lu", (ulong) len, (ulong) type->prec); diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index 6f0a81296ac..4233cb05773 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -24,6 +24,7 @@ Created 1/8/1996 Heikki Tuuri #include "pars0pars.h" #include "trx0roll.h" #include "usr0sess.h" +#include "ut0vec.h" /********************************************************************* Based on a table object, this function builds the entry to be inserted @@ -74,14 +75,14 @@ dict_create_sys_tables_tuple( dfield = dtuple_get_nth_field(entry, 3); ptr = mem_heap_alloc(heap, 4); - mach_write_to_4(ptr, table->type); + mach_write_to_4(ptr, DICT_TABLE_ORDINARY); dfield_set_data(dfield, ptr, 4); /* 6: MIX_ID ---------------------------*/ dfield = dtuple_get_nth_field(entry, 4); ptr = mem_heap_alloc(heap, 8); - mach_write_to_8(ptr, table->mix_id); + memset(ptr, 0, 8); dfield_set_data(dfield, ptr, 8); /* 7: MIX_LEN --------------------------*/ @@ -89,19 +90,13 @@ dict_create_sys_tables_tuple( dfield = dtuple_get_nth_field(entry, 5); ptr = mem_heap_alloc(heap, 4); - mach_write_to_4(ptr, table->mix_len); + memset(ptr, 0, 4); dfield_set_data(dfield, ptr, 4); /* 8: CLUSTER_NAME ---------------------*/ dfield = dtuple_get_nth_field(entry, 6); + dfield_set_data(dfield, NULL, UNIV_SQL_NULL); /* not supported */ - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - dfield_set_data(dfield, table->cluster_name, - ut_strlen(table->cluster_name)); - ut_error; /* Oracle-style clusters are not supported yet */ - } else { - dfield_set_data(dfield, NULL, UNIV_SQL_NULL); - } /* 9: SPACE ----------------------------*/ dfield = dtuple_get_nth_field(entry, 7); @@ -207,7 +202,6 @@ dict_build_table_def_step( tab_node_t* node) /* in: table create node */ { dict_table_t* table; - dict_table_t* cluster_table; dtuple_t* row; ulint error; const char* path_or_name; @@ -235,23 +229,6 @@ dict_build_table_def_step( return(DB_TOO_BIG_RECORD); } - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - - cluster_table = dict_table_get_low(table->cluster_name); - - if (cluster_table == NULL) { - - return(DB_CLUSTER_NOT_FOUND); - } - - /* Inherit space and mix len from the cluster */ - - table->space = cluster_table->space; - table->mix_len = cluster_table->mix_len; - - table->mix_id = dict_hdr_get_new_id(DICT_HDR_MIX_ID); - } - if (srv_file_per_table) { /* We create a new single-table tablespace for the table. We initially let it be 4 pages: @@ -614,15 +591,6 @@ dict_create_index_tree_step( sys_indexes = dict_sys->sys_indexes; - if (index->type & DICT_CLUSTERED - && table->type == DICT_TABLE_CLUSTER_MEMBER) { - - /* Do not create a new index tree: entries are put to the - cluster tree */ - - return(DB_SUCCESS); - } - /* Run a mini-transaction in which the index tree is allocated for the index and its root address is written to the index entry in sys_indexes */ @@ -1159,11 +1127,8 @@ dict_create_or_check_foreign_constraint_tables(void) { dict_table_t* table1; dict_table_t* table2; - que_thr_t* thr; - que_t* graph; ulint error; trx_t* trx; - const char* str; mutex_enter(&(dict_sys->mutex)); @@ -1215,7 +1180,7 @@ dict_create_or_check_foreign_constraint_tables(void) VARBINARY, like in other InnoDB system tables, to get a clean design. */ - str = + error = que_eval_sql(NULL, "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n" "BEGIN\n" "CREATE TABLE\n" @@ -1227,22 +1192,8 @@ dict_create_or_check_foreign_constraint_tables(void) "SYS_FOREIGN_COLS(ID CHAR, POS INT, FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" "CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);\n" "COMMIT WORK;\n" - "END;\n"; - - graph = pars_sql(str); - - ut_a(graph); - - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - - ut_a(thr = que_fork_start_command(graph)); - - que_run_threads(thr); - - error = trx->error_state; + "END;\n" + , trx); if (error != DB_SUCCESS) { fprintf(stderr, "InnoDB: error %lu in creation\n", @@ -1261,8 +1212,6 @@ dict_create_or_check_foreign_constraint_tables(void) error = DB_MUST_GET_MORE_FILE_SPACE; } - que_graph_free(graph); - trx->op_info = ""; row_mysql_unlock_data_dictionary(trx); @@ -1277,150 +1226,23 @@ dict_create_or_check_foreign_constraint_tables(void) return(error); } -/************************************************************************ -Adds foreign key definitions to data dictionary tables in the database. We -look at table->foreign_list, and also generate names to constraints that were -not named by the user. A generated constraint has a name of the format -databasename/tablename_ibfk_<number>, where the numbers start from 1, and are -given locally for this table, that is, the number is not global, as in the -old format constraints < 4.0.18 it used to be. */ +/******************************************************************** +Evaluate the given foreign key SQL statement. */ ulint -dict_create_add_foreigns_to_dictionary( -/*===================================*/ +dict_foreign_eval_sql( +/*==================*/ /* out: error code or DB_SUCCESS */ - ulint start_id,/* in: if we are actually doing ALTER TABLE - ADD CONSTRAINT, we want to generate constraint - numbers which are bigger than in the table so - far; we number the constraints from - start_id + 1 up; start_id should be set to 0 if - we are creating a new table, or if the table - so far has no constraints for which the name - was generated here */ + pars_info_t* info, /* in: info struct, or NULL */ + const char* sql, /* in: SQL string to evaluate */ dict_table_t* table, /* in: table */ + dict_foreign_t* foreign,/* in: foreign */ trx_t* trx) /* in: transaction */ { - dict_foreign_t* foreign; - que_thr_t* thr; - que_t* graph; - ulint number = start_id + 1; - ulint len; ulint error; FILE* ef = dict_foreign_err_file; - ulint i; - char* sql; - char* sqlend; - /* This procedure builds an InnoDB stored procedure which will insert - the necessary rows into SYS_FOREIGN and SYS_FOREIGN_COLS. */ - static const char str1[] = "PROCEDURE ADD_FOREIGN_DEFS_PROC () IS\n" - "BEGIN\n" - "INSERT INTO SYS_FOREIGN VALUES("; - static const char str2[] = ");\n"; - static const char str3[] = - "INSERT INTO SYS_FOREIGN_COLS VALUES("; - static const char str4[] = - "COMMIT WORK;\n" - "END;\n"; -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - - if (NULL == dict_table_get_low("SYS_FOREIGN")) { - fprintf(stderr, -"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n"); - - return(DB_ERROR); - } - - foreign = UT_LIST_GET_FIRST(table->foreign_list); -loop: - if (foreign == NULL) { - - return(DB_SUCCESS); - } - - if (foreign->id == NULL) { - /* Generate a new constraint id */ - ulint namelen = strlen(table->name); - char* id = mem_heap_alloc(foreign->heap, namelen + 20); - /* no overflow if number < 1e13 */ - sprintf(id, "%s_ibfk_%lu", table->name, (ulong) number++); - foreign->id = id; - } - - len = (sizeof str1) + (sizeof str2) + (sizeof str4) - 3 - + 9/* ' and , chars */ + 10/* 32-bit integer */ - + ut_strlenq(foreign->id, '\'') * (foreign->n_fields + 1) - + ut_strlenq(table->name, '\'') - + ut_strlenq(foreign->referenced_table_name, '\''); - - for (i = 0; i < foreign->n_fields; i++) { - len += 9/* ' and , chars */ + 10/* 32-bit integer */ - + (sizeof str3) + (sizeof str2) - 2 - + ut_strlenq(foreign->foreign_col_names[i], '\'') - + ut_strlenq(foreign->referenced_col_names[i], '\''); - } - - sql = sqlend = mem_alloc(len + 1); - - /* INSERT INTO SYS_FOREIGN VALUES(...); */ - memcpy(sqlend, str1, (sizeof str1) - 1); - sqlend += (sizeof str1) - 1; - *sqlend++ = '\''; - sqlend = ut_strcpyq(sqlend, '\'', foreign->id); - *sqlend++ = '\'', *sqlend++ = ',', *sqlend++ = '\''; - sqlend = ut_strcpyq(sqlend, '\'', table->name); - *sqlend++ = '\'', *sqlend++ = ',', *sqlend++ = '\''; - sqlend = ut_strcpyq(sqlend, '\'', foreign->referenced_table_name); - *sqlend++ = '\'', *sqlend++ = ','; - sqlend += sprintf(sqlend, "%010lu", - foreign->n_fields + (foreign->type << 24)); - memcpy(sqlend, str2, (sizeof str2) - 1); - sqlend += (sizeof str2) - 1; - - for (i = 0; i < foreign->n_fields; i++) { - /* INSERT INTO SYS_FOREIGN_COLS VALUES(...); */ - memcpy(sqlend, str3, (sizeof str3) - 1); - sqlend += (sizeof str3) - 1; - *sqlend++ = '\''; - sqlend = ut_strcpyq(sqlend, '\'', foreign->id); - *sqlend++ = '\''; *sqlend++ = ','; - sqlend += sprintf(sqlend, "%010lu", (ulong) i); - *sqlend++ = ','; *sqlend++ = '\''; - sqlend = ut_strcpyq(sqlend, '\'', - foreign->foreign_col_names[i]); - *sqlend++ = '\''; *sqlend++ = ','; *sqlend++ = '\''; - sqlend = ut_strcpyq(sqlend, '\'', - foreign->referenced_col_names[i]); - *sqlend++ = '\''; - memcpy(sqlend, str2, (sizeof str2) - 1); - sqlend += (sizeof str2) - 1; - } - - memcpy(sqlend, str4, sizeof str4); - sqlend += sizeof str4; - - ut_a(sqlend == sql + len + 1); - - graph = pars_sql(sql); - - ut_a(graph); - - mem_free(sql); - - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - - ut_a(thr = que_fork_start_command(graph)); - - que_run_threads(thr); - - error = trx->error_state; - - que_graph_free(graph); + error = que_eval_sql(info, sql, trx); if (error == DB_DUPLICATE_KEY) { mutex_enter(&dict_foreign_err_mutex); @@ -1466,7 +1288,163 @@ loop: return(error); } - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); + return(DB_SUCCESS); +} + +/************************************************************************ +Add a single foreign key field definition to the data dictionary tables in +the database. */ +static +ulint +dict_create_add_foreign_field_to_dictionary( +/*========================================*/ + /* out: error code or DB_SUCCESS */ + ulint field_nr, /* in: foreign field number */ + dict_table_t* table, /* in: table */ + dict_foreign_t* foreign, /* in: foreign */ + trx_t* trx) /* in: transaction */ +{ + pars_info_t* info = pars_info_create(); + + pars_info_add_str_literal(info, "id", foreign->id); + + pars_info_add_int4_literal(info, "pos", field_nr); + + pars_info_add_str_literal(info, "for_col_name", + foreign->foreign_col_names[field_nr]); + + pars_info_add_str_literal(info, "ref_col_name", + foreign->referenced_col_names[field_nr]); + + return dict_foreign_eval_sql(info, + "PROCEDURE P () IS\n" + "BEGIN\n" + "INSERT INTO SYS_FOREIGN_COLS VALUES" + "(:id, :pos, :for_col_name, :ref_col_name);\n" + "END;\n" + , table, foreign, trx); +} + +/************************************************************************ +Add a single foreign key definition to the data dictionary tables in the +database. We also generate names to constraints that were not named by the +user. A generated constraint has a name of the format +databasename/tablename_ibfk_<number>, where the numbers start from 1, and +are given locally for this table, that is, the number is not global, as in +the old format constraints < 4.0.18 it used to be. */ +static +ulint +dict_create_add_foreign_to_dictionary( +/*==================================*/ + /* out: error code or DB_SUCCESS */ + ulint* id_nr, /* in/out: number to use in id generation; + incremented if used */ + dict_table_t* table, /* in: table */ + dict_foreign_t* foreign,/* in: foreign */ + trx_t* trx) /* in: transaction */ +{ + ulint error; + ulint i; + + pars_info_t* info = pars_info_create(); + + if (foreign->id == NULL) { + /* Generate a new constraint id */ + ulint namelen = strlen(table->name); + char* id = mem_heap_alloc(foreign->heap, namelen + 20); + /* no overflow if number < 1e13 */ + sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++); + foreign->id = id; + } + + pars_info_add_str_literal(info, "id", foreign->id); + + pars_info_add_str_literal(info, "for_name", table->name); + + pars_info_add_str_literal(info, "ref_name", + foreign->referenced_table_name); + + pars_info_add_int4_literal(info, "n_cols", + foreign->n_fields + (foreign->type << 24)); + + error = dict_foreign_eval_sql(info, + "PROCEDURE P () IS\n" + "BEGIN\n" + "INSERT INTO SYS_FOREIGN VALUES" + "(:id, :for_name, :ref_name, :n_cols);\n" + "END;\n" + , table, foreign, trx); + + if (error != DB_SUCCESS) { + + return(error); + } + + for (i = 0; i < foreign->n_fields; i++) { + error = dict_create_add_foreign_field_to_dictionary(i, + table, foreign, trx); + + if (error != DB_SUCCESS) { + + return(error); + } + } + + error = dict_foreign_eval_sql(NULL, + "PROCEDURE P () IS\n" + "BEGIN\n" + "COMMIT WORK;\n" + "END;\n" + , table, foreign, trx); - goto loop; + return(error); +} + +/************************************************************************ +Adds foreign key definitions to data dictionary tables in the database. */ + +ulint +dict_create_add_foreigns_to_dictionary( +/*===================================*/ + /* out: error code or DB_SUCCESS */ + ulint start_id,/* in: if we are actually doing ALTER TABLE + ADD CONSTRAINT, we want to generate constraint + numbers which are bigger than in the table so + far; we number the constraints from + start_id + 1 up; start_id should be set to 0 if + we are creating a new table, or if the table + so far has no constraints for which the name + was generated here */ + dict_table_t* table, /* in: table */ + trx_t* trx) /* in: transaction */ +{ + dict_foreign_t* foreign; + ulint number = start_id + 1; + ulint error; + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(dict_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ + + if (NULL == dict_table_get_low("SYS_FOREIGN")) { + fprintf(stderr, +"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n"); + + return(DB_ERROR); + } + + for (foreign = UT_LIST_GET_FIRST(table->foreign_list); + foreign; + foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) { + + error = dict_create_add_foreign_to_dictionary(&number, + table, foreign, trx); + + if (error != DB_SUCCESS) { + + return(error); + } + } + + return(DB_SUCCESS); } diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 1fac5e26fa9..877d4afe8f0 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -658,6 +658,19 @@ dict_table_get_nth_col_pos( } /************************************************************************ +Check whether the table uses the compact page format. */ + +ibool +dict_table_is_comp_noninline( +/*=========================*/ + /* out: TRUE if table uses the + compact page format */ + const dict_table_t* table) /* in: table */ +{ + return(dict_table_is_comp(table)); +} + +/************************************************************************ Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. */ @@ -870,13 +883,6 @@ dict_table_add_to_cache( ut_a(table2 == NULL); } - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - - table->mix_id_len = mach_dulint_get_compressed_size( - table->mix_id); - mach_dulint_write_compressed(table->mix_id_buf, table->mix_id); - } - /* Add the columns to the column hash table */ for (i = 0; i < table->n_cols; i++) { dict_col_add_to_cache(table, dict_table_get_nth_col(table, i)); @@ -1251,15 +1257,13 @@ dict_table_remove_from_cache( /* Remove table from LRU list of tables */ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); - mutex_free(&(table->autoinc_mutex)); - size = mem_heap_get_size(table->heap); ut_ad(dict_sys->size >= size); dict_sys->size -= size; - mem_heap_free(table->heap); + dict_mem_table_free(table); } /************************************************************************** @@ -1380,6 +1384,38 @@ dict_col_reposition_in_cache( HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col); } +/******************************************************************** +If the given column name is reserved for InnoDB system columns, return +TRUE. */ + +ibool +dict_col_name_is_reserved( +/*======================*/ + /* out: TRUE if name is reserved */ + const char* name) /* in: column name */ +{ + /* This check reminds that if a new system column is added to + the program, it should be dealt with here. */ +#if DATA_N_SYS_COLS != 4 +#error "DATA_N_SYS_COLS != 4" +#endif + + static const char* reserved_names[] = { + "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID" + }; + + ulint i; + + for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) { + if (strcmp(name, reserved_names[i]) == 0) { + + return(TRUE); + } + } + + return(FALSE); +} + /************************************************************************** Adds an index to the dictionary cache. */ @@ -1394,7 +1430,6 @@ dict_index_add_to_cache( { dict_index_t* new_index; dict_tree_t* tree; - dict_table_t* cluster; dict_field_t* field; ulint n_ord; ibool success; @@ -1468,21 +1503,11 @@ dict_index_add_to_cache( dict_field_get_col(field)->ord_part++; } - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - /* The index tree is found from the cluster object */ - - cluster = dict_table_get_low(table->cluster_name); + /* Create an index tree memory object for the index */ + tree = dict_tree_create(new_index, page_no); + ut_ad(tree); - tree = dict_index_get_tree( - UT_LIST_GET_FIRST(cluster->indexes)); - new_index->tree = tree; - } else { - /* Create an index tree memory object for the index */ - tree = dict_tree_create(new_index, page_no); - ut_ad(tree); - - new_index->tree = tree; - } + new_index->tree = tree; if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) { @@ -1500,7 +1525,7 @@ dict_index_add_to_cache( } /* Add the index to the list of indexes stored in the tree */ - UT_LIST_ADD_LAST(tree_indexes, tree->tree_indexes, new_index); + tree->tree_index = new_index; /* If the dictionary cache grows too big, trim the table LRU list */ @@ -1532,7 +1557,7 @@ dict_index_remove_from_cache( ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - ut_ad(UT_LIST_GET_LEN((index->tree)->tree_indexes) == 1); + ut_ad(index->tree->tree_index); dict_tree_free(index->tree); /* Decrement the ord_part counts in columns which are ordering */ @@ -1553,7 +1578,7 @@ dict_index_remove_from_cache( dict_sys->size -= size; - mem_heap_free(index->heap); + dict_mem_index_free(index); } /*********************************************************************** @@ -1699,8 +1724,6 @@ dict_table_copy_types( dtype_t* type; ulint i; - ut_ad(!(table->type & DICT_UNIVERSAL)); - for (i = 0; i < dtuple_get_n_fields(tuple); i++) { dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i)); @@ -1749,22 +1772,8 @@ dict_index_build_internal_clust( new_index->id = index->id; - if (table->type != DICT_TABLE_ORDINARY) { - /* The index is mixed: copy common key prefix fields */ - - dict_index_copy(new_index, index, 0, table->mix_len); - - /* Add the mix id column */ - dict_index_add_col(new_index, - dict_table_get_sys_col(table, DATA_MIX_ID), 0); - - /* Copy the rest of fields */ - dict_index_copy(new_index, index, table->mix_len, - index->n_fields); - } else { - /* Copy the fields of index */ - dict_index_copy(new_index, index, 0, index->n_fields); - } + /* Copy the fields of index */ + dict_index_copy(new_index, index, 0, index->n_fields); if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { /* No fixed number of fields determines an entry uniquely */ @@ -3641,7 +3650,7 @@ dict_tree_create( tree->id = index->id; - UT_LIST_INIT(tree->tree_indexes); + tree->tree_index = NULL; tree->magic_n = DICT_TREE_MAGIC_N; @@ -3667,135 +3676,7 @@ dict_tree_free( mem_free(tree); } -/************************************************************************** -In an index tree, finds the index corresponding to a record in the tree. */ -UNIV_INLINE -dict_index_t* -dict_tree_find_index_low( -/*=====================*/ - /* out: index */ - dict_tree_t* tree, /* in: index tree */ - rec_t* rec) /* in: record for which to find correct - index */ -{ - dict_index_t* index; - dict_table_t* table; - dulint mix_id; - ulint len; - - index = UT_LIST_GET_FIRST(tree->tree_indexes); - ut_ad(index); - table = index->table; - - if ((index->type & DICT_CLUSTERED) - && UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) { - - /* Get the mix id of the record */ - ut_a(!dict_table_is_comp(table)); - - mix_id = mach_dulint_read_compressed( - rec_get_nth_field_old(rec, table->mix_len, &len)); - - while (ut_dulint_cmp(table->mix_id, mix_id) != 0) { - - index = UT_LIST_GET_NEXT(tree_indexes, index); - table = index->table; - ut_ad(index); - } - } - - return(index); -} - -/************************************************************************** -In an index tree, finds the index corresponding to a record in the tree. */ - -dict_index_t* -dict_tree_find_index( -/*=================*/ - /* out: index */ - dict_tree_t* tree, /* in: index tree */ - rec_t* rec) /* in: record for which to find correct - index */ -{ - dict_index_t* index; - - index = dict_tree_find_index_low(tree, rec); - - return(index); -} - -/************************************************************************** -In an index tree, finds the index corresponding to a dtuple which is used -in a search to a tree. */ - -dict_index_t* -dict_tree_find_index_for_tuple( -/*===========================*/ - /* out: index; NULL if the tuple does not - contain the mix id field in a mixed tree */ - dict_tree_t* tree, /* in: index tree */ - dtuple_t* tuple) /* in: tuple for which to find index */ -{ - dict_index_t* index; - dict_table_t* table; - dulint mix_id; - - ut_ad(dtuple_check_typed(tuple)); - - if (UT_LIST_GET_LEN(tree->tree_indexes) == 1) { - - return(UT_LIST_GET_FIRST(tree->tree_indexes)); - } - - index = UT_LIST_GET_FIRST(tree->tree_indexes); - ut_ad(index); - table = index->table; - - if (dtuple_get_n_fields(tuple) <= table->mix_len) { - - return(NULL); - } - - /* Get the mix id of the record */ - - mix_id = mach_dulint_read_compressed( - dfield_get_data( - dtuple_get_nth_field(tuple, table->mix_len))); - - while (ut_dulint_cmp(table->mix_id, mix_id) != 0) { - - index = UT_LIST_GET_NEXT(tree_indexes, index); - table = index->table; - ut_ad(index); - } - - return(index); -} - -/*********************************************************************** -Checks if a table which is a mixed cluster member owns a record. */ - -ibool -dict_is_mixed_table_rec( -/*====================*/ - /* out: TRUE if the record belongs to this - table */ - dict_table_t* table, /* in: table in a mixed cluster */ - rec_t* rec) /* in: user record in the clustered index */ -{ - byte* mix_id_field; - ulint len; - - ut_ad(!dict_table_is_comp(table)); - - mix_id_field = rec_get_nth_field_old(rec, - table->mix_len, &len); - - return(len == table->mix_id_len - && !ut_memcmp(table->mix_id_buf, mix_id_field, len)); -} - +#ifdef UNIV_DEBUG /************************************************************************** Checks that a tuple has n_fields_cmp value in a sensible range, so that no comparison can occur with the page number field in a node pointer. */ @@ -3807,19 +3688,14 @@ dict_tree_check_search_tuple( dict_tree_t* tree, /* in: index tree */ dtuple_t* tuple) /* in: tuple used in a search */ { - dict_index_t* index; - - index = dict_tree_find_index_for_tuple(tree, tuple); - - if (index == NULL) { - - return(TRUE); - } + dict_index_t* index = tree->tree_index; + ut_a(index); ut_a(dtuple_get_n_fields_cmp(tuple) <= dict_index_get_n_unique_in_tree(index)); return(TRUE); } +#endif /* UNIV_DEBUG */ /************************************************************************** Builds a node pointer out of a physical record and a page number. */ @@ -3842,7 +3718,7 @@ dict_tree_build_node_ptr( byte* buf; ulint n_unique; - ind = dict_tree_find_index_low(tree, rec); + ind = tree->tree_index; if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) { /* In a universal index tree, we take the whole record as @@ -3910,7 +3786,7 @@ dict_tree_copy_rec_order_prefix( ulint n; UNIV_PREFETCH_R(rec); - index = dict_tree_find_index_low(tree, rec); + index = tree->tree_index; if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) { ut_a(!dict_table_is_comp(index->table)); @@ -3938,7 +3814,7 @@ dict_tree_build_data_tuple( dtuple_t* tuple; dict_index_t* ind; - ind = dict_tree_find_index_low(tree, rec); + ind = tree->tree_index; ut_ad(dict_table_is_comp(ind->table) || n_fields <= rec_get_n_fields_old(rec)); @@ -4097,6 +3973,18 @@ dict_update_statistics( } /************************************************************************** +A noninlined version of dict_table_get_low. */ + +dict_table_t* +dict_table_get_low_noninlined( +/*==========================*/ + /* out: table, NULL if not found */ + const char* table_name) /* in: table name */ +{ + return(dict_table_get_low(table_name)); +} + +/************************************************************************** Prints info of a foreign key constraint. */ static void @@ -4520,15 +4408,3 @@ dict_index_name_print( fputs(" of table ", file); ut_print_name(file, trx, index->table_name); } - -/************************************************************************ -Export an inlined function for use in ha_innodb.c. */ -ibool -innodb_dict_table_is_comp( -/*===============*/ - /* out: TRUE if table uses the - compact page format */ - const dict_table_t* table) /* in: table */ -{ - return dict_table_is_comp(table); -} diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 09935c03288..4779e50f176 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -768,7 +768,7 @@ dict_load_table( if (!btr_pcur_is_on_user_rec(&pcur, &mtr) || rec_get_deleted_flag(rec, 0)) { /* Not found */ - + err_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); @@ -780,11 +780,8 @@ dict_load_table( /* Check if the table name in record is the searched one */ if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) { - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - return(NULL); + goto err_exit; } ut_a(0 == ut_strcmp("SPACE", @@ -848,36 +845,17 @@ dict_load_table( table->id = mach_read_from_8(field); field = rec_get_nth_field_old(rec, 5, &len); - table->type = mach_read_from_4(field); - - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - ut_error; -#if 0 /* clustered tables have not been implemented yet */ - field = rec_get_nth_field_old(rec, 6, &len); - table->mix_id = mach_read_from_8(field); - - field = rec_get_nth_field_old(rec, 8, &len); - table->cluster_name = mem_heap_strdupl(heap, (char*) field, len); -#endif - } - - if ((table->type == DICT_TABLE_CLUSTER) - || (table->type == DICT_TABLE_CLUSTER_MEMBER)) { - - field = rec_get_nth_field_old(rec, 7, &len); - ut_a(len == 4); - table->mix_len = mach_read_from_4(field); + if (UNIV_UNLIKELY(mach_read_from_4(field) != DICT_TABLE_ORDINARY)) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: table %s: unknown table type %lu\n", + name, (ulong) mach_read_from_4(field)); + goto err_exit; } btr_pcur_close(&pcur); mtr_commit(&mtr); - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - /* Load the cluster table definition if not yet in - memory cache */ - dict_table_get_low(table->cluster_name); - } - dict_load_columns(table, heap); dict_table_add_to_cache(table); diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c index d9f0ad3d84e..fe21890adc8 100644 --- a/storage/innobase/dict/dict0mem.c +++ b/storage/innobase/dict/dict0mem.c @@ -50,7 +50,6 @@ dict_mem_table_create( table->heap = heap; - table->type = DICT_TABLE_ORDINARY; table->flags = flags; table->name = mem_heap_strdup(heap, name); table->dir_path_of_temp_table = NULL; @@ -66,9 +65,6 @@ dict_mem_table_create( table->cached = FALSE; - table->mix_id = ut_dulint_zero; - table->mix_len = 0; - table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS) * sizeof(dict_col_t)); UT_LIST_INIT(table->indexes); @@ -97,42 +93,19 @@ dict_mem_table_create( return(table); } -/************************************************************************** -Creates a cluster memory object. */ - -dict_table_t* -dict_mem_cluster_create( -/*====================*/ - /* out, own: cluster object */ - const char* name, /* in: cluster name */ - ulint space, /* in: space where the clustered indexes - of the member tables are placed */ - ulint n_cols, /* in: number of columns */ - ulint mix_len)/* in: length of the common key prefix in the - cluster */ -{ - dict_table_t* cluster; - - /* Clustered tables cannot work with the compact record format. */ - cluster = dict_mem_table_create(name, space, n_cols, 0); - - cluster->type = DICT_TABLE_CLUSTER; - cluster->mix_len = mix_len; - - return(cluster); -} - -/************************************************************************** -Declares a non-published table as a member in a cluster. */ +/******************************************************************** +Free a table memory object. */ void -dict_mem_table_make_cluster_member( -/*===============================*/ - dict_table_t* table, /* in: non-published table */ - const char* cluster_name) /* in: cluster name */ +dict_mem_table_free( +/*================*/ + dict_table_t* table) /* in: table */ { - table->type = DICT_TABLE_CLUSTER_MEMBER; - table->cluster_name = cluster_name; + ut_ad(table); + ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); + + mutex_free(&(table->autoinc_mutex)); + mem_heap_free(table->heap); } /************************************************************************** @@ -286,5 +259,8 @@ dict_mem_index_free( /*================*/ dict_index_t* index) /* in: index */ { + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + mem_heap_free(index->heap); } diff --git a/storage/innobase/eval/eval0proc.c b/storage/innobase/eval/eval0proc.c index dcbdc0da5fc..96b8ef75955 100644 --- a/storage/innobase/eval/eval0proc.c +++ b/storage/innobase/eval/eval0proc.c @@ -213,6 +213,38 @@ for_step( } /************************************************************************** +Performs an execution step of an exit statement node. */ + +que_thr_t* +exit_step( +/*======*/ + /* out: query thread to run next or NULL */ + que_thr_t* thr) /* in: query thread */ +{ + exit_node_t* node; + que_node_t* loop_node; + + ut_ad(thr); + + node = thr->run_node; + + ut_ad(que_node_get_type(node) == QUE_NODE_EXIT); + + /* Loops exit by setting thr->run_node as the loop node's parent, so + find our containing loop node and get its parent. */ + + loop_node = que_node_get_containing_loop_node(node); + + /* If someone uses an EXIT statement outside of a loop, this will + trigger. */ + ut_a(loop_node); + + thr->run_node = que_node_get_parent(loop_node); + + return(thr); +} + +/************************************************************************** Performs an execution step of a return-statement node. */ que_thr_t* diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 36cc97e5e0e..3263a0efd5b 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -1170,9 +1170,9 @@ ibuf_dummy_index_free( dict_index_t* index) /* in: dummy index */ { dict_table_t* table = index->table; - mem_heap_free(index->heap); - mutex_free(&(table->autoinc_mutex)); - mem_heap_free(table->heap); + + dict_mem_index_free(index); + dict_mem_table_free(table); } /************************************************************************* diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index cb6cb1b1a4d..d5dd4f3010a 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -459,7 +459,10 @@ btr_store_big_rec_extern_fields( dict_index_t* index, /* in: index of rec; the index tree MUST be X-latched */ rec_t* rec, /* in: record */ - const ulint* offsets, /* in: rec_get_offsets(rec, index) */ + const ulint* offsets, /* in: rec_get_offsets(rec, index); + the "external storage" flags in offsets + will not correspond to rec when + this function returns */ big_rec_t* big_rec_vec, /* in: vector containing fields to be stored externally */ mtr_t* local_mtr); /* in: mtr containing the latch to diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic index 5d2ae768416..a199c3d4d32 100644 --- a/storage/innobase/include/btr0cur.ic +++ b/storage/innobase/include/btr0cur.ic @@ -98,8 +98,7 @@ btr_cur_compress_recommendation( { page_t* page; - ut_ad(mtr_memo_contains(mtr, buf_block_align( - btr_cur_get_page(cursor)), + ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)), MTR_MEMO_PAGE_X_FIX)); page = btr_cur_get_page(cursor); @@ -142,8 +141,7 @@ btr_cur_can_delete_without_compress( { page_t* page; - ut_ad(mtr_memo_contains(mtr, buf_block_align( - btr_cur_get_page(cursor)), + ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_rec(cursor)), MTR_MEMO_PAGE_X_FIX)); page = btr_cur_get_page(cursor); diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index b64d5e62e03..62b1d2db559 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -180,12 +180,14 @@ struct btr_search_struct{ the same prefix should be indexed in the hash index */ /*----------------------*/ +#ifdef UNIV_SEARCH_PERF_STAT ulint n_hash_succ; /* number of successful hash searches thus far */ ulint n_hash_fail; /* number of failed hash searches */ ulint n_patt_succ; /* number of successful pattern searches thus far */ ulint n_searches; /* number of searches */ +#endif /* UNIV_SEARCH_PERF_STAT */ }; #define BTR_SEARCH_MAGIC_N 1112765 @@ -218,8 +220,8 @@ extern rw_lock_t* btr_search_latch_temp; #ifdef UNIV_SEARCH_PERF_STAT extern ulint btr_search_n_succ; -#endif /* UNIV_SEARCH_PERF_STAT */ extern ulint btr_search_n_hash_fail; +#endif /* UNIV_SEARCH_PERF_STAT */ /* After change in n_fields or n_bytes in info, this many rounds are waited before starting the hash analysis again: this is to save CPU time when there diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index f8150db0437..6d26fd4d3b2 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -26,14 +26,14 @@ void buf_LRU_try_free_flushed_blocks(void); /*==================================*/ /********************************************************************** -Returns TRUE if less than 15 % of the buffer pool is available. This can be +Returns TRUE if less than 25 % of the buffer pool is available. This can be used in heuristics to prevent huge transactions eating up the whole buffer pool for their locks. */ ibool buf_LRU_buf_pool_running_out(void); /*==============================*/ - /* out: TRUE if less than 15 % of buffer pool + /* out: TRUE if less than 25 % of buffer pool left */ /*####################################################################### diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 9de5c5b52d5..39cde5bfb55 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -100,6 +100,15 @@ ulint dict_col_get_clust_pos( /*===================*/ dict_col_t* col); +/******************************************************************** +If the given column name is reserved for InnoDB system columns, return +TRUE. */ + +ibool +dict_col_name_is_reserved( +/*======================*/ + /* out: TRUE if name is reserved */ + const char* name); /* in: column name */ /************************************************************************ Initializes the autoinc counter. It is not an error to initialize an already initialized counter. */ @@ -321,6 +330,14 @@ dict_table_get_low( /* out: table, NULL if not found */ const char* table_name); /* in: table name */ /************************************************************************** +A noninlined version of dict_table_get_low. */ + +dict_table_t* +dict_table_get_low_noninlined( +/*==========================*/ + /* out: table, NULL if not found */ + const char* table_name); /* in: table name */ +/************************************************************************** Returns an index object. */ UNIV_INLINE dict_index_t* @@ -496,10 +513,11 @@ dict_table_is_comp( compact page format */ const dict_table_t* table); /* in: table */ /************************************************************************ -Non inlined version of 'dict_table_is_comp' above. */ +Check whether the table uses the compact page format. */ + ibool -innodb_dict_table_is_comp( -/*===============*/ +dict_table_is_comp_noninline( +/*=========================*/ /* out: TRUE if table uses the compact page format */ const dict_table_t* table); /* in: table */ @@ -725,33 +743,6 @@ dict_tree_free( /************************************************************************** In an index tree, finds the index corresponding to a record in the tree. */ -dict_index_t* -dict_tree_find_index( -/*=================*/ - /* out: index */ - dict_tree_t* tree, /* in: index tree */ - rec_t* rec); /* in: record for which to find correct index */ -/************************************************************************** -In an index tree, finds the index corresponding to a dtuple which is used -in a search to a tree. */ - -dict_index_t* -dict_tree_find_index_for_tuple( -/*===========================*/ - /* out: index; NULL if the tuple does not - contain the mix id field in a mixed tree */ - dict_tree_t* tree, /* in: index tree */ - dtuple_t* tuple); /* in: tuple for which to find index */ -/*********************************************************************** -Checks if a table which is a mixed cluster member owns a record. */ - -ibool -dict_is_mixed_table_rec( -/*====================*/ - /* out: TRUE if the record belongs to this - table */ - dict_table_t* table, /* in: table in a mixed cluster */ - rec_t* rec); /* in: user record in the clustered index */ /************************************************************************** Returns an index object if it is found in the dictionary cache. */ @@ -760,6 +751,7 @@ dict_index_get_if_in_cache( /*=======================*/ /* out: index, NULL if not found */ dulint index_id); /* in: index id */ +#ifdef UNIV_DEBUG /************************************************************************** Checks that a tuple has n_fields_cmp value in a sensible range, so that no comparison can occur with the page number field in a node pointer. */ @@ -770,6 +762,7 @@ dict_tree_check_search_tuple( /* out: TRUE if ok */ dict_tree_t* tree, /* in: index tree */ dtuple_t* tuple); /* in: tuple used in a search */ +#endif /* UNIV_DEBUG */ /************************************************************************** Builds a node pointer out of a physical record and a page number. */ @@ -916,7 +909,6 @@ dict_tables_have_same_db( dbname '/' tablename */ const char* name2); /* in: table name in the form dbname '/' tablename */ - /************************************************************************* Scans from pointer onwards. Stops if is at the start of a copy of 'string' where characters are compared without case sensitivity. Stops @@ -928,7 +920,6 @@ dict_scan_to( /* out: scanned up to this */ const char* ptr, /* in: scan from */ const char* string);/* in: look for this */ - /* Buffers for storing detailed information about the latest foreign key and unique key errors */ extern FILE* dict_foreign_err_file; diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index b99ca7815a8..0b5a23e9380 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -92,7 +92,6 @@ dict_table_get_n_user_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols - DATA_N_SYS_COLS); } @@ -126,7 +125,6 @@ dict_table_get_n_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols); } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index ab07213de3b..0135ba3874d 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -35,9 +35,11 @@ combination of types */ /* Types for a table object */ #define DICT_TABLE_ORDINARY 1 +#if 0 /* not implemented */ #define DICT_TABLE_CLUSTER_MEMBER 2 #define DICT_TABLE_CLUSTER 3 /* this means that the table is really a cluster definition */ +#endif /* Table flags */ #define DICT_TF_COMPACT 1 /* compact page format */ @@ -56,29 +58,13 @@ dict_mem_table_create( a member of a cluster */ ulint n_cols, /* in: number of columns */ ulint flags); /* in: table flags */ -/************************************************************************** -Creates a cluster memory object. */ - -dict_cluster_t* -dict_mem_cluster_create( -/*====================*/ - /* out, own: cluster object (where the - type dict_cluster_t == dict_table_t) */ - const char* name, /* in: cluster name */ - ulint space, /* in: space where the clustered - indexes of the member tables are - placed */ - ulint n_cols, /* in: number of columns */ - ulint mix_len); /* in: length of the common key prefix - in the cluster */ -/************************************************************************** -Declares a non-published table as a member in a cluster. */ +/******************************************************************** +Free a table memory object. */ void -dict_mem_table_make_cluster_member( -/*===============================*/ - dict_table_t* table, /* in: non-published table */ - const char* cluster_name); /* in: cluster name */ +dict_mem_table_free( +/*================*/ + dict_table_t* table); /* in: table */ /************************************************************************** Adds a column definition to a table. */ @@ -176,9 +162,7 @@ struct dict_field_struct{ /* Data structure for an index tree */ struct dict_tree_struct{ ulint type; /* tree type */ - dulint id; /* id of the index stored in the tree, in the - case of a mixed index, the id of the clustered - index of the cluster table */ + dulint id; /* id of the index stored in the tree */ ulint space; /* space of index tree */ ulint page; /* index tree root page number */ byte pad[64];/* Padding to prevent other memory hotspots on @@ -189,13 +173,8 @@ struct dict_tree_struct{ struct has been memoryfixed (by mini- transactions wanting to access the index tree) */ - UT_LIST_BASE_NODE_T(dict_index_t) - tree_indexes; /* list of indexes stored in the - index tree: if the tree is not of the - mixed type there is only one index in - the list; if the tree is of the mixed - type, the first index in the list is the - index of the cluster which owns the tree */ + dict_index_t* tree_index; /* the index stored in the + index tree */ ulint magic_n;/* magic number */ }; @@ -301,8 +280,7 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ /* Data structure for a database table */ struct dict_table_struct{ - dulint id; /* id of the table or cluster */ - ulint type; /* DICT_TABLE_ORDINARY, ... */ + dulint id; /* id of the table */ ulint flags; /* DICT_TF_COMPACT, ... */ mem_heap_t* heap; /* memory heap */ const char* name; /* table name */ @@ -371,17 +349,6 @@ struct dict_table_struct{ UT_LIST_BASE_NODE_T(lock_t) locks; /* list of locks on the table */ /*----------------------*/ - dulint mix_id; /* if the table is a member in a cluster, - this is its mix id */ - ulint mix_len;/* if the table is a cluster or a member - this is the common key prefix lenght */ - ulint mix_id_len;/* mix id length in a compressed form */ - byte mix_id_buf[12]; - /* mix id of a mixed table written in - a compressed form */ - const char* cluster_name; /* if the table is a member in a - cluster, this is the name of the cluster */ - /*----------------------*/ ibool does_not_fit_in_memory; /* this field is used to specify in simulations tables which are so big that disk should be diff --git a/storage/innobase/include/eval0proc.h b/storage/innobase/include/eval0proc.h index 2cf98f26265..8416551d0ba 100644 --- a/storage/innobase/include/eval0proc.h +++ b/storage/innobase/include/eval0proc.h @@ -63,6 +63,14 @@ proc_eval_step( /* out: query thread to run next or NULL */ que_thr_t* thr); /* in: query thread */ /************************************************************************** +Performs an execution step of an exit statement node. */ + +que_thr_t* +exit_step( +/*======*/ + /* out: query thread to run next or NULL */ + que_thr_t* thr); /* in: query thread */ +/************************************************************************** Performs an execution step of a return-statement node. */ que_thr_t* diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h index a5cd32d956f..31c5c57ae35 100644 --- a/storage/innobase/include/hash0hash.h +++ b/storage/innobase/include/hash0hash.h @@ -222,6 +222,32 @@ do {\ mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));\ } while (0) +/******************************************************************** +Move all hash table entries from OLD_TABLE to NEW_TABLE.*/ + +#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, FOLD_FUNC) \ +do {\ + ulint i2222;\ + ulint cell_count2222;\ +\ + cell_count2222 = hash_get_n_cells(OLD_TABLE);\ +\ + for (i2222 = 0; i2222 < cell_count2222; i2222++) {\ + NODE_TYPE* node2222 = HASH_GET_FIRST((OLD_TABLE), i2222);\ +\ + while (node2222) {\ + NODE_TYPE* next2222 = node2222->PTR_NAME;\ + ulint fold2222 = FOLD_FUNC(node2222);\ +\ + HASH_INSERT(NODE_TYPE, PTR_NAME, (NEW_TABLE),\ + fold2222, node2222);\ +\ + node2222 = next2222;\ + }\ + }\ +} while (0) + + /**************************************************************** Gets the mutex index for a fold value in a hash table. */ UNIV_INLINE diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 3dda3a7cca8..6b863e32183 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -595,6 +595,15 @@ ibool lock_validate(void); /*===============*/ /* out: TRUE if ok */ +/************************************************************************* +Return approximate number or record locks (bits set in the bitmap) for +this transaction. Since delete-marked records ma ybe removed, the +record count will not be precise. */ + +ulint +lock_number_of_rows_locked( +/*=======================*/ + trx_t* trx); /* in: transaction */ /* The lock system */ extern lock_sys_t* lock_sys; diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h index e2f8be98b01..f9342e962f2 100644 --- a/storage/innobase/include/mem0mem.h +++ b/storage/innobase/include/mem0mem.h @@ -311,6 +311,17 @@ mem_heap_strdupl( const char* str, /* in: string to be copied */ ulint len); /* in: length of str, in bytes */ +/************************************************************************** +Concatenate two strings and return the result, using a memory heap. */ + +char* +mem_heap_strcat( +/*============*/ + /* out, own: the result */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* s1, /* in: string 1 */ + const char* s2); /* in: string 2 */ + #ifdef MEM_PERIODIC_CHECK /********************************************************************** Goes through the list of all allocated mem blocks, checks their magic diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index 2f651b40319..b33eeaceb1c 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -175,19 +175,6 @@ page_rec_is_comp( /* out: nonzero if in compact format */ const rec_t* rec) /* in: record */ { -#ifdef UNIV_RELEASE_NOT_YET_STABLE - if (UNIV_UNLIKELY((ulint)rec < (ulint)(buf_pool->frame_zero)) - || UNIV_UNLIKELY((ulint)rec >= (ulint)(buf_pool->high_end))) { - - ut_print_timestamp(stderr); - fprintf(stderr, -"InnoDB: Error: trying to read a stray page rec %p\n" -"InnoDB: buf pool start is at %p, end at %p\n", - rec, buf_pool->frame_zero, - buf_pool->high_end); - ut_error; - } -#endif return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE))); } diff --git a/storage/innobase/include/pars0grm.h b/storage/innobase/include/pars0grm.h index e35fcf47692..996fc37f13b 100644 --- a/storage/innobase/include/pars0grm.h +++ b/storage/innobase/include/pars0grm.h @@ -32,177 +32,187 @@ PARS_INT_LIT = 258, PARS_FLOAT_LIT = 259, PARS_STR_LIT = 260, - PARS_NULL_LIT = 261, - PARS_ID_TOKEN = 262, - PARS_AND_TOKEN = 263, - PARS_OR_TOKEN = 264, - PARS_NOT_TOKEN = 265, - PARS_GE_TOKEN = 266, - PARS_LE_TOKEN = 267, - PARS_NE_TOKEN = 268, - PARS_PROCEDURE_TOKEN = 269, - PARS_IN_TOKEN = 270, - PARS_OUT_TOKEN = 271, - PARS_BINARY_TOKEN = 272, - PARS_BLOB_TOKEN = 273, - PARS_INT_TOKEN = 274, - PARS_INTEGER_TOKEN = 275, - PARS_FLOAT_TOKEN = 276, - PARS_CHAR_TOKEN = 277, - PARS_IS_TOKEN = 278, - PARS_BEGIN_TOKEN = 279, - PARS_END_TOKEN = 280, - PARS_IF_TOKEN = 281, - PARS_THEN_TOKEN = 282, - PARS_ELSE_TOKEN = 283, - PARS_ELSIF_TOKEN = 284, - PARS_LOOP_TOKEN = 285, - PARS_WHILE_TOKEN = 286, - PARS_RETURN_TOKEN = 287, - PARS_SELECT_TOKEN = 288, - PARS_SUM_TOKEN = 289, - PARS_COUNT_TOKEN = 290, - PARS_DISTINCT_TOKEN = 291, - PARS_FROM_TOKEN = 292, - PARS_WHERE_TOKEN = 293, - PARS_FOR_TOKEN = 294, - PARS_DDOT_TOKEN = 295, - PARS_CONSISTENT_TOKEN = 296, - PARS_READ_TOKEN = 297, - PARS_ORDER_TOKEN = 298, - PARS_BY_TOKEN = 299, - PARS_ASC_TOKEN = 300, - PARS_DESC_TOKEN = 301, - PARS_INSERT_TOKEN = 302, - PARS_INTO_TOKEN = 303, - PARS_VALUES_TOKEN = 304, - PARS_UPDATE_TOKEN = 305, - PARS_SET_TOKEN = 306, - PARS_DELETE_TOKEN = 307, - PARS_CURRENT_TOKEN = 308, - PARS_OF_TOKEN = 309, - PARS_CREATE_TOKEN = 310, - PARS_TABLE_TOKEN = 311, - PARS_INDEX_TOKEN = 312, - PARS_UNIQUE_TOKEN = 313, - PARS_CLUSTERED_TOKEN = 314, - PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 315, - PARS_ON_TOKEN = 316, - PARS_ASSIGN_TOKEN = 317, - PARS_DECLARE_TOKEN = 318, - PARS_CURSOR_TOKEN = 319, - PARS_SQL_TOKEN = 320, - PARS_OPEN_TOKEN = 321, - PARS_FETCH_TOKEN = 322, - PARS_CLOSE_TOKEN = 323, - PARS_NOTFOUND_TOKEN = 324, - PARS_TO_CHAR_TOKEN = 325, - PARS_TO_NUMBER_TOKEN = 326, - PARS_TO_BINARY_TOKEN = 327, - PARS_BINARY_TO_NUMBER_TOKEN = 328, - PARS_SUBSTR_TOKEN = 329, - PARS_REPLSTR_TOKEN = 330, - PARS_CONCAT_TOKEN = 331, - PARS_INSTR_TOKEN = 332, - PARS_LENGTH_TOKEN = 333, - PARS_SYSDATE_TOKEN = 334, - PARS_PRINTF_TOKEN = 335, - PARS_ASSERT_TOKEN = 336, - PARS_RND_TOKEN = 337, - PARS_RND_STR_TOKEN = 338, - PARS_ROW_PRINTF_TOKEN = 339, - PARS_COMMIT_TOKEN = 340, - PARS_ROLLBACK_TOKEN = 341, - PARS_WORK_TOKEN = 342, - NEG = 343 + PARS_FIXBINARY_LIT = 261, + PARS_BLOB_LIT = 262, + PARS_NULL_LIT = 263, + PARS_ID_TOKEN = 264, + PARS_AND_TOKEN = 265, + PARS_OR_TOKEN = 266, + PARS_NOT_TOKEN = 267, + PARS_GE_TOKEN = 268, + PARS_LE_TOKEN = 269, + PARS_NE_TOKEN = 270, + PARS_PROCEDURE_TOKEN = 271, + PARS_IN_TOKEN = 272, + PARS_OUT_TOKEN = 273, + PARS_BINARY_TOKEN = 274, + PARS_BLOB_TOKEN = 275, + PARS_INT_TOKEN = 276, + PARS_INTEGER_TOKEN = 277, + PARS_FLOAT_TOKEN = 278, + PARS_CHAR_TOKEN = 279, + PARS_IS_TOKEN = 280, + PARS_BEGIN_TOKEN = 281, + PARS_END_TOKEN = 282, + PARS_IF_TOKEN = 283, + PARS_THEN_TOKEN = 284, + PARS_ELSE_TOKEN = 285, + PARS_ELSIF_TOKEN = 286, + PARS_LOOP_TOKEN = 287, + PARS_WHILE_TOKEN = 288, + PARS_RETURN_TOKEN = 289, + PARS_SELECT_TOKEN = 290, + PARS_SUM_TOKEN = 291, + PARS_COUNT_TOKEN = 292, + PARS_DISTINCT_TOKEN = 293, + PARS_FROM_TOKEN = 294, + PARS_WHERE_TOKEN = 295, + PARS_FOR_TOKEN = 296, + PARS_DDOT_TOKEN = 297, + PARS_CONSISTENT_TOKEN = 298, + PARS_READ_TOKEN = 299, + PARS_ORDER_TOKEN = 300, + PARS_BY_TOKEN = 301, + PARS_ASC_TOKEN = 302, + PARS_DESC_TOKEN = 303, + PARS_INSERT_TOKEN = 304, + PARS_INTO_TOKEN = 305, + PARS_VALUES_TOKEN = 306, + PARS_UPDATE_TOKEN = 307, + PARS_SET_TOKEN = 308, + PARS_DELETE_TOKEN = 309, + PARS_CURRENT_TOKEN = 310, + PARS_OF_TOKEN = 311, + PARS_CREATE_TOKEN = 312, + PARS_TABLE_TOKEN = 313, + PARS_INDEX_TOKEN = 314, + PARS_UNIQUE_TOKEN = 315, + PARS_CLUSTERED_TOKEN = 316, + PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317, + PARS_ON_TOKEN = 318, + PARS_ASSIGN_TOKEN = 319, + PARS_DECLARE_TOKEN = 320, + PARS_CURSOR_TOKEN = 321, + PARS_SQL_TOKEN = 322, + PARS_OPEN_TOKEN = 323, + PARS_FETCH_TOKEN = 324, + PARS_CLOSE_TOKEN = 325, + PARS_NOTFOUND_TOKEN = 326, + PARS_TO_CHAR_TOKEN = 327, + PARS_TO_NUMBER_TOKEN = 328, + PARS_TO_BINARY_TOKEN = 329, + PARS_BINARY_TO_NUMBER_TOKEN = 330, + PARS_SUBSTR_TOKEN = 331, + PARS_REPLSTR_TOKEN = 332, + PARS_CONCAT_TOKEN = 333, + PARS_INSTR_TOKEN = 334, + PARS_LENGTH_TOKEN = 335, + PARS_SYSDATE_TOKEN = 336, + PARS_PRINTF_TOKEN = 337, + PARS_ASSERT_TOKEN = 338, + PARS_RND_TOKEN = 339, + PARS_RND_STR_TOKEN = 340, + PARS_ROW_PRINTF_TOKEN = 341, + PARS_COMMIT_TOKEN = 342, + PARS_ROLLBACK_TOKEN = 343, + PARS_WORK_TOKEN = 344, + PARS_UNSIGNED_TOKEN = 345, + PARS_EXIT_TOKEN = 346, + PARS_FUNCTION_TOKEN = 347, + NEG = 348 }; #endif #define PARS_INT_LIT 258 #define PARS_FLOAT_LIT 259 #define PARS_STR_LIT 260 -#define PARS_NULL_LIT 261 -#define PARS_ID_TOKEN 262 -#define PARS_AND_TOKEN 263 -#define PARS_OR_TOKEN 264 -#define PARS_NOT_TOKEN 265 -#define PARS_GE_TOKEN 266 -#define PARS_LE_TOKEN 267 -#define PARS_NE_TOKEN 268 -#define PARS_PROCEDURE_TOKEN 269 -#define PARS_IN_TOKEN 270 -#define PARS_OUT_TOKEN 271 -#define PARS_BINARY_TOKEN 272 -#define PARS_BLOB_TOKEN 273 -#define PARS_INT_TOKEN 274 -#define PARS_INTEGER_TOKEN 275 -#define PARS_FLOAT_TOKEN 276 -#define PARS_CHAR_TOKEN 277 -#define PARS_IS_TOKEN 278 -#define PARS_BEGIN_TOKEN 279 -#define PARS_END_TOKEN 280 -#define PARS_IF_TOKEN 281 -#define PARS_THEN_TOKEN 282 -#define PARS_ELSE_TOKEN 283 -#define PARS_ELSIF_TOKEN 284 -#define PARS_LOOP_TOKEN 285 -#define PARS_WHILE_TOKEN 286 -#define PARS_RETURN_TOKEN 287 -#define PARS_SELECT_TOKEN 288 -#define PARS_SUM_TOKEN 289 -#define PARS_COUNT_TOKEN 290 -#define PARS_DISTINCT_TOKEN 291 -#define PARS_FROM_TOKEN 292 -#define PARS_WHERE_TOKEN 293 -#define PARS_FOR_TOKEN 294 -#define PARS_DDOT_TOKEN 295 -#define PARS_CONSISTENT_TOKEN 296 -#define PARS_READ_TOKEN 297 -#define PARS_ORDER_TOKEN 298 -#define PARS_BY_TOKEN 299 -#define PARS_ASC_TOKEN 300 -#define PARS_DESC_TOKEN 301 -#define PARS_INSERT_TOKEN 302 -#define PARS_INTO_TOKEN 303 -#define PARS_VALUES_TOKEN 304 -#define PARS_UPDATE_TOKEN 305 -#define PARS_SET_TOKEN 306 -#define PARS_DELETE_TOKEN 307 -#define PARS_CURRENT_TOKEN 308 -#define PARS_OF_TOKEN 309 -#define PARS_CREATE_TOKEN 310 -#define PARS_TABLE_TOKEN 311 -#define PARS_INDEX_TOKEN 312 -#define PARS_UNIQUE_TOKEN 313 -#define PARS_CLUSTERED_TOKEN 314 -#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 315 -#define PARS_ON_TOKEN 316 -#define PARS_ASSIGN_TOKEN 317 -#define PARS_DECLARE_TOKEN 318 -#define PARS_CURSOR_TOKEN 319 -#define PARS_SQL_TOKEN 320 -#define PARS_OPEN_TOKEN 321 -#define PARS_FETCH_TOKEN 322 -#define PARS_CLOSE_TOKEN 323 -#define PARS_NOTFOUND_TOKEN 324 -#define PARS_TO_CHAR_TOKEN 325 -#define PARS_TO_NUMBER_TOKEN 326 -#define PARS_TO_BINARY_TOKEN 327 -#define PARS_BINARY_TO_NUMBER_TOKEN 328 -#define PARS_SUBSTR_TOKEN 329 -#define PARS_REPLSTR_TOKEN 330 -#define PARS_CONCAT_TOKEN 331 -#define PARS_INSTR_TOKEN 332 -#define PARS_LENGTH_TOKEN 333 -#define PARS_SYSDATE_TOKEN 334 -#define PARS_PRINTF_TOKEN 335 -#define PARS_ASSERT_TOKEN 336 -#define PARS_RND_TOKEN 337 -#define PARS_RND_STR_TOKEN 338 -#define PARS_ROW_PRINTF_TOKEN 339 -#define PARS_COMMIT_TOKEN 340 -#define PARS_ROLLBACK_TOKEN 341 -#define PARS_WORK_TOKEN 342 -#define NEG 343 +#define PARS_FIXBINARY_LIT 261 +#define PARS_BLOB_LIT 262 +#define PARS_NULL_LIT 263 +#define PARS_ID_TOKEN 264 +#define PARS_AND_TOKEN 265 +#define PARS_OR_TOKEN 266 +#define PARS_NOT_TOKEN 267 +#define PARS_GE_TOKEN 268 +#define PARS_LE_TOKEN 269 +#define PARS_NE_TOKEN 270 +#define PARS_PROCEDURE_TOKEN 271 +#define PARS_IN_TOKEN 272 +#define PARS_OUT_TOKEN 273 +#define PARS_BINARY_TOKEN 274 +#define PARS_BLOB_TOKEN 275 +#define PARS_INT_TOKEN 276 +#define PARS_INTEGER_TOKEN 277 +#define PARS_FLOAT_TOKEN 278 +#define PARS_CHAR_TOKEN 279 +#define PARS_IS_TOKEN 280 +#define PARS_BEGIN_TOKEN 281 +#define PARS_END_TOKEN 282 +#define PARS_IF_TOKEN 283 +#define PARS_THEN_TOKEN 284 +#define PARS_ELSE_TOKEN 285 +#define PARS_ELSIF_TOKEN 286 +#define PARS_LOOP_TOKEN 287 +#define PARS_WHILE_TOKEN 288 +#define PARS_RETURN_TOKEN 289 +#define PARS_SELECT_TOKEN 290 +#define PARS_SUM_TOKEN 291 +#define PARS_COUNT_TOKEN 292 +#define PARS_DISTINCT_TOKEN 293 +#define PARS_FROM_TOKEN 294 +#define PARS_WHERE_TOKEN 295 +#define PARS_FOR_TOKEN 296 +#define PARS_DDOT_TOKEN 297 +#define PARS_CONSISTENT_TOKEN 298 +#define PARS_READ_TOKEN 299 +#define PARS_ORDER_TOKEN 300 +#define PARS_BY_TOKEN 301 +#define PARS_ASC_TOKEN 302 +#define PARS_DESC_TOKEN 303 +#define PARS_INSERT_TOKEN 304 +#define PARS_INTO_TOKEN 305 +#define PARS_VALUES_TOKEN 306 +#define PARS_UPDATE_TOKEN 307 +#define PARS_SET_TOKEN 308 +#define PARS_DELETE_TOKEN 309 +#define PARS_CURRENT_TOKEN 310 +#define PARS_OF_TOKEN 311 +#define PARS_CREATE_TOKEN 312 +#define PARS_TABLE_TOKEN 313 +#define PARS_INDEX_TOKEN 314 +#define PARS_UNIQUE_TOKEN 315 +#define PARS_CLUSTERED_TOKEN 316 +#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317 +#define PARS_ON_TOKEN 318 +#define PARS_ASSIGN_TOKEN 319 +#define PARS_DECLARE_TOKEN 320 +#define PARS_CURSOR_TOKEN 321 +#define PARS_SQL_TOKEN 322 +#define PARS_OPEN_TOKEN 323 +#define PARS_FETCH_TOKEN 324 +#define PARS_CLOSE_TOKEN 325 +#define PARS_NOTFOUND_TOKEN 326 +#define PARS_TO_CHAR_TOKEN 327 +#define PARS_TO_NUMBER_TOKEN 328 +#define PARS_TO_BINARY_TOKEN 329 +#define PARS_BINARY_TO_NUMBER_TOKEN 330 +#define PARS_SUBSTR_TOKEN 331 +#define PARS_REPLSTR_TOKEN 332 +#define PARS_CONCAT_TOKEN 333 +#define PARS_INSTR_TOKEN 334 +#define PARS_LENGTH_TOKEN 335 +#define PARS_SYSDATE_TOKEN 336 +#define PARS_PRINTF_TOKEN 337 +#define PARS_ASSERT_TOKEN 338 +#define PARS_RND_TOKEN 339 +#define PARS_RND_STR_TOKEN 340 +#define PARS_ROW_PRINTF_TOKEN 341 +#define PARS_COMMIT_TOKEN 342 +#define PARS_ROLLBACK_TOKEN 343 +#define PARS_WORK_TOKEN 344 +#define PARS_UNSIGNED_TOKEN 345 +#define PARS_EXIT_TOKEN 346 +#define PARS_FUNCTION_TOKEN 347 +#define NEG 348 diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index 2ae2d6cff74..68b8ae41cc0 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -15,6 +15,13 @@ Created 11/19/1996 Heikki Tuuri #include "pars0types.h" #include "row0types.h" #include "trx0types.h" +#include "ut0vec.h" + +/* Type of the user functions. The first argument is always InnoDB-supplied +and varies in type, while 'user_arg' is a user-supplied argument. The +meaning of the return type also varies. See the individual use cases, e.g. +the FETCH statement, for details on them. */ +typedef void* (*pars_user_func_cb_t)(void* arg, void* user_arg); extern int yydebug; @@ -77,6 +84,7 @@ que_t* pars_sql( /*=====*/ /* out, own: the query graph */ + pars_info_t* info, /* in: extra information, or NULL */ const char* str); /* in: SQL string */ /***************************************************************** Retrieves characters to the lexical analyzer. */ @@ -157,6 +165,15 @@ pars_cursor_declaration( table */ sel_node_t* select_node); /* in: select node */ /************************************************************************* +Parses a function declaration. */ + +que_node_t* +pars_function_declaration( +/*======================*/ + /* out: sym_node */ + sym_node_t* sym_node); /* in: function id node in the symbol + table */ +/************************************************************************* Parses a select statement. */ sel_node_t* @@ -269,6 +286,13 @@ pars_while_statement( que_node_t* cond, /* in: while-condition */ que_node_t* stat_list); /* in: statement list */ /************************************************************************* +Parses an exit statement. */ + +exit_node_t* +pars_exit_statement(void); +/*=====================*/ + /* out: exit statement node */ +/************************************************************************* Parses a return-statement. */ return_node_t* @@ -294,14 +318,16 @@ pars_assignment_statement( sym_node_t* var, /* in: variable to assign */ que_node_t* val); /* in: value to assign */ /************************************************************************* -Parses a fetch statement. */ +Parses a fetch statement. into_list or user_func (but not both) must be +non-NULL. */ fetch_node_t* pars_fetch_statement( /*=================*/ /* out: fetch statement node */ sym_node_t* cursor, /* in: cursor node */ - sym_node_t* into_list); /* in: variables to set */ + sym_node_t* into_list, /* in: variables to set, or NULL */ + sym_node_t* user_func); /* in: user function name, or NULL */ /************************************************************************* Parses an open or close cursor statement. */ @@ -345,6 +371,8 @@ pars_column_def( pars_res_word_t* type, /* in: data type */ sym_node_t* len, /* in: length of column, or NULL */ + void* is_unsigned, /* in: if not NULL, column + is of type UNSIGNED. */ void* is_not_null); /* in: if not NULL, column is of type NOT NULL. */ /************************************************************************* @@ -418,6 +446,142 @@ pars_complete_graph_for_exec( trx_t* trx, /* in: transaction handle */ mem_heap_t* heap); /* in: memory heap from which allocated */ +/******************************************************************** +Create parser info struct.*/ + +pars_info_t* +pars_info_create(void); +/*==================*/ + /* out, own: info struct */ + +/******************************************************************** +Free info struct and everything it contains.*/ + +void +pars_info_free( +/*===========*/ + pars_info_t* info); /* in: info struct */ + +/******************************************************************** +Add bound literal. */ + +void +pars_info_add_literal( +/*==================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + const void* address, /* in: address */ + ulint length, /* in: length of data */ + ulint type, /* in: type, e.g. DATA_FIXBINARY */ + ulint prtype); /* in: precise type, e.g. + DATA_UNSIGNED */ + +/******************************************************************** +Equivalent to pars_info_add_literal(info, name, str, strlen(str), +DATA_VARCHAR, DATA_ENGLISH). */ + +void +pars_info_add_str_literal( +/*======================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + const char* str); /* in: string */ + +/******************************************************************** +Equivalent to: + +char buf[4]; +mach_write_to_4(buf, val); +pars_info_add_literal(info, name, buf, 4, DATA_INT, 0); + +except that the buffer is dynamically allocated from the info struct's +heap. */ + +void +pars_info_add_int4_literal( +/*=======================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + lint val); /* in: value */ + +/******************************************************************** +Equivalent to: + +char buf[8]; +mach_write_to_8(buf, val); +pars_info_add_literal(info, name, buf, 8, DATA_BINARY, 0); + +except that the buffer is dynamically allocated from the info struct's +heap. */ + +void +pars_info_add_dulint_literal( +/*=========================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + dulint val); /* in: value */ +/******************************************************************** +Add user function. */ + +void +pars_info_add_function( +/*===================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: function name */ + pars_user_func_cb_t func, /* in: function address */ + void* arg); /* in: user-supplied argument */ + +/******************************************************************** +Get user function with the given name.*/ + +pars_user_func_t* +pars_info_get_user_func( +/*====================*/ + /* out: user func, or NULL if not + found */ + pars_info_t* info, /* in: info struct */ + const char* name); /* in: function name to find*/ + +/******************************************************************** +Get bound literal with the given name.*/ + +pars_bound_lit_t* +pars_info_get_bound_lit( +/*====================*/ + /* out: bound literal, or NULL if + not found */ + pars_info_t* info, /* in: info struct */ + const char* name); /* in: bound literal name to find */ + + +/* Extra information supplied for pars_sql(). */ +struct pars_info_struct { + mem_heap_t* heap; /* our own memory heap */ + + ib_vector_t* funcs; /* user functions, or NUll + (pars_user_func_t*) */ + ib_vector_t* bound_lits; /* bound literals, or NULL + (pars_bound_lit_t*) */ + + ibool graph_owns_us; /* if TRUE (which is the default), + que_graph_free() will free us */ +}; + +/* User-supplied function and argument. */ +struct pars_user_func_struct { + const char* name; /* function name */ + pars_user_func_cb_t func; /* function address */ + void* arg; /* user-supplied argument */ +}; + +/* Bound literal. */ +struct pars_bound_lit_struct { + const char* name; /* name */ + const void* address; /* address */ + ulint length; /* length of data */ + ulint type; /* type, e.g. DATA_FIXBINARY */ + ulint prtype; /* precise type, e.g. DATA_UNSIGNED */ +}; /* Struct used to denote a reserved word in a parsing tree */ struct pars_res_word_struct{ @@ -498,6 +662,11 @@ struct for_node_struct{ que_node_t* stat_list; /* statement list */ }; +/* exit statement node */ +struct exit_node_struct{ + que_common_t common; /* type: QUE_NODE_EXIT */ +}; + /* return-statement node */ struct return_node_struct{ que_common_t common; /* type: QUE_NODE_RETURN */ diff --git a/storage/innobase/include/pars0sym.h b/storage/innobase/include/pars0sym.h index a10d70d48b6..14f762d5b7a 100644 --- a/storage/innobase/include/pars0sym.h +++ b/storage/innobase/include/pars0sym.h @@ -54,6 +54,16 @@ sym_tab_add_str_lit( it */ ulint len); /* in: string length */ /********************************************************************** +Add a bound literal to a symbol table. */ + +sym_node_t* +sym_tab_add_bound_lit( +/*==================*/ + /* out: symbol table node */ + sym_tab_t* sym_tab, /* in: symbol table */ + const char* name, /* in: name of bound literal */ + ulint* lit_type); /* out: type of literal (PARS_*_LIT) */ +/********************************************************************** Adds an SQL null literal to a symbol table. */ sym_node_t* @@ -83,6 +93,19 @@ struct sym_node_struct{ been allocated from dynamic memory and it should be freed when the symbol table is discarded */ + /* 'alias' and 'indirection' are almost the same, but not quite. + 'alias' always points to the primary instance of the variable, while + 'indirection' does the same only if we should use the primary + instance's values for the node's data. This is usually the case, but + when initializing a cursor (e.g., "DECLARE CURSOR c IS SELECT * FROM + t WHERE id = x;"), we copy the values from the primary instance to + the cursor's instance so that they are fixed for the duration of the + cursor, and set 'indirection' to NULL. If we did not, the value of + 'x' could change between fetches and things would break horribly. + + TODO: It would be cleaner to make 'indirection' a boolean field and + always use 'alias' to refer to the primary node. */ + sym_node_t* indirection; /* pointer to another symbol table node which contains @@ -158,6 +181,7 @@ struct sym_tab_struct{ /* position of the next character in sql_string to give to the lexical analyzer */ + pars_info_t* info; /* extra information, or NULL */ sym_node_list_t sym_list; /* list of symbol nodes in the symbol table */ @@ -180,6 +204,7 @@ struct sym_tab_struct{ #define SYM_CURSOR 96 /* named cursor */ #define SYM_PROCEDURE_NAME 97 /* stored procedure name */ #define SYM_INDEX 98 /* database index name */ +#define SYM_FUNCTION 99 /* user function name */ #ifndef UNIV_NONINL #include "pars0sym.ic" diff --git a/storage/innobase/include/pars0types.h b/storage/innobase/include/pars0types.h index cf62617e066..6fcfaf23024 100644 --- a/storage/innobase/include/pars0types.h +++ b/storage/innobase/include/pars0types.h @@ -9,6 +9,9 @@ Created 1/11/1998 Heikki Tuuri #ifndef pars0types_h #define pars0types_h +typedef struct pars_info_struct pars_info_t; +typedef struct pars_user_func_struct pars_user_func_t; +typedef struct pars_bound_lit_struct pars_bound_lit_t; typedef struct sym_node_struct sym_node_t; typedef struct sym_tab_struct sym_tab_t; typedef struct pars_res_word_struct pars_res_word_t; @@ -19,6 +22,7 @@ typedef struct elsif_node_struct elsif_node_t; typedef struct if_node_struct if_node_t; typedef struct while_node_struct while_node_t; typedef struct for_node_struct for_node_t; +typedef struct exit_node_struct exit_node_t; typedef struct return_node_struct return_node_t; typedef struct assign_node_struct assign_node_t; typedef struct col_assign_node_struct col_assign_node_t; diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index 4e31e2db4b7..c3314a1167b 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -277,6 +277,15 @@ que_node_get_parent( /*================*/ /* out: parent node or NULL */ que_node_t* node); /* in: node */ +/******************************************************************** +Get the first containing loop node (e.g. while_node_t or for_node_t) for the +given node, or NULL if the node is not within a loop. */ + +que_node_t* +que_node_get_containing_loop_node( +/*==============================*/ + /* out: containing loop node, or NULL. */ + que_node_t* node); /* in: node */ /************************************************************************* Catenates a query graph node to a list of them, possible empty list. */ UNIV_INLINE @@ -322,8 +331,15 @@ void que_node_print_info( /*================*/ que_node_t* node); /* in: query graph node */ +/************************************************************************* +Evaluate the given SQL */ - +ulint +que_eval_sql( +/*=========*/ + pars_info_t* info, /* out: error code or DB_SUCCESS */ + const char* sql, /* in: info struct, or NULL */ + trx_t* trx); /* in: trx */ /* Query graph query thread node: the fields are protected by the kernel mutex with the exceptions named below */ @@ -388,6 +404,7 @@ struct que_fork_struct{ sym_tab_t* sym_tab; /* symbol table of the query, generated by the parser, or NULL if the graph was created 'by hand' */ + pars_info_t* info; /* in: info struct, or NULL */ /* The following cur_... fields are relevant only in a select graph */ ulint cur_end; /* QUE_CUR_NOT_DEFINED, QUE_CUR_START, @@ -469,6 +486,7 @@ struct que_fork_struct{ #define QUE_NODE_ROW_PRINTF 29 #define QUE_NODE_ELSIF 30 #define QUE_NODE_CALL 31 +#define QUE_NODE_EXIT 32 /* Query thread states */ #define QUE_THR_RUNNING 1 diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 8ff8a0476a1..48fb7432b54 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -244,7 +244,8 @@ row_update_for_mysql( row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL handle */ /************************************************************************* -This can only be used when srv_locks_unsafe_for_binlog is TRUE. Before +This can only be used when srv_locks_unsafe_for_binlog is TRUE or +session is using a READ COMMITTED isolation level. Before calling this function we must use trx_reset_new_rec_lock_info() and trx_register_new_rec_lock() to store the information which new record locks really were set. This function removes a newly set lock under prebuilt->pcur, diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index c9f2389d3dd..70b08d82994 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -78,6 +78,26 @@ fetch_step( /*=======*/ /* out: query thread to run next or NULL */ que_thr_t* thr); /* in: query thread */ +/******************************************************************** +Sample callback function for fetch that prints each row.*/ + +void* +row_fetch_print( +/*============*/ + /* out: always returns non-NULL */ + void* row, /* in: sel_node_t* */ + void* user_arg); /* in: not used */ +/******************************************************************** +Callback function for fetch that stores an unsigned 4 byte integer to the +location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length += 4. */ + +void* +row_fetch_store_uint4( +/*==================*/ + /* out: always returns NULL */ + void* row, /* in: sel_node_t* */ + void* user_arg); /* in: data pointer */ /*************************************************************** Prints a row in a select result. */ @@ -204,8 +224,6 @@ struct plan_struct{ ulint first_prefetched;/* index of the first cached row in select buffer arrays for each column */ ibool no_prefetch; /* no prefetch for this table */ - ibool mixed_index; /* TRUE if index is a clustered index - in a mixed cluster */ sym_node_list_t columns; /* symbol table nodes for the columns to retrieve from the table */ UT_LIST_BASE_NODE_T(func_node_t) @@ -311,6 +329,20 @@ struct fetch_node_struct{ que_common_t common; /* type: QUE_NODE_FETCH */ sel_node_t* cursor_def; /* cursor definition */ sym_node_t* into_list; /* variables to set */ + + pars_user_func_t* + func; /* User callback function or NULL. + The first argument to the function + is a sel_node_t*, containing the + results of the SELECT operation for + one row. If the function returns + NULL, it is not interested in + further rows and the cursor is + modified so (cursor % NOTFOUND) is + true. If it returns not-NULL, + continue normally. See + row_fetch_print() for an example + (and a useful debugging tool). */ }; /* Open or close cursor statement node */ diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index 41cce851d87..efbc6d6facf 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -185,6 +185,10 @@ row_upd_index_replace_new_col_vals_index_pos( upd_t* update, /* in: an update vector built for the index so that the field number in an upd_field is the index position */ + ibool order_only, + /* in: if TRUE, limit the replacement to + ordering fields of index; note that this + does not work for non-clustered indexes. */ mem_heap_t* heap); /* in: memory heap to which we allocate and copy the new values, set this as NULL if you do not want allocation */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 4278d602675..838b5b546c7 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -544,7 +544,9 @@ struct trx_struct{ the transaction; note that it is also in the lock list trx_locks */ dict_index_t* new_rec_locks[2];/* these are normally NULL; if - srv_locks_unsafe_for_binlog is TRUE, + srv_locks_unsafe_for_binlog is TRUE + or session is using READ COMMITTED + isolation level, in a cursor search, if we set a new record lock on an index, this is set to point to the index; this is diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index de57f6f07b8..5b294ae0769 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -82,10 +82,6 @@ memory is read outside the allocated blocks. */ /* Make a non-inline debug version */ -/* You can remove this define when the release is stable. This define adds -some consistency checks to code. They use a little CPU time. */ -#define UNIV_RELEASE_NOT_YET_STABLE - /* #define UNIV_DEBUG #define UNIV_MEM_DEBUG @@ -128,7 +124,7 @@ by one. */ #ifdef __WIN__ #define UNIV_INLINE __inline #else -#define UNIV_INLINE static inline +#define UNIV_INLINE static __inline__ #endif #else @@ -178,6 +174,16 @@ management to ensure correct alignment for doubles etc. */ /* Note that inside MySQL 'byte' is defined as char on Linux! */ #define byte unsigned char +/* Define an unsigned integer type that is exactly 32 bits. */ + +#if SIZEOF_INT == 4 +typedef unsigned int ib_uint32_t; +#elif SIZEOF_LONG == 4 +typedef unsigned long ib_uint32_t; +#else +#error "Neither int or long is 4 bytes" +#endif + /* Another basic type we use is unsigned long integer which should be equal to the word size of the machine, that is on a 32-bit platform 32 bits, and on a 64-bit platform 64 bits. We also give the printf format for the type as a @@ -205,9 +211,6 @@ typedef longlong ib_longlong; #endif #endif -/* The following type should be at least a 64-bit floating point number */ -typedef double utfloat; - /* The 'undefined' value for a ulint */ #define ULINT_UNDEFINED ((ulint)(-1)) diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h index 6e4a265349f..90c16f4fad5 100644 --- a/storage/innobase/include/ut0mem.h +++ b/storage/innobase/include/ut0mem.h @@ -181,6 +181,30 @@ ut_memcpyq( const char* src, /* in: string to be quoted */ ulint len); /* in: length of src */ +/************************************************************************** +Return the number of times s2 occurs in s1. Overlapping instances of s2 +are only counted once. */ + +ulint +ut_strcount( +/*========*/ + /* out: the number of times s2 occurs in s1 */ + const char* s1, /* in: string to search in */ + const char* s2); /* in: string to search for */ + +/************************************************************************** +Replace every occurrence of s1 in str with s2. Overlapping instances of s1 +are only replaced once. */ + +char * +ut_strreplace( +/*==========*/ + /* out, own: modified string, must be + freed with mem_free() */ + const char* str, /* in: string to operate on */ + const char* s1, /* in: string to replace */ + const char* s2); /* in: string to replace s1 with */ + #ifndef UNIV_NONINL #include "ut0mem.ic" #endif diff --git a/storage/innobase/include/ut0vec.h b/storage/innobase/include/ut0vec.h new file mode 100644 index 00000000000..e0cc4dfb009 --- /dev/null +++ b/storage/innobase/include/ut0vec.h @@ -0,0 +1,73 @@ +#ifndef IB_VECTOR_H +#define IB_VECTOR_H + +#include "univ.i" +#include "mem0mem.h" + +typedef struct ib_vector_struct ib_vector_t; + +/* An automatically resizing vector datatype with the following properties: + + -Contains void* items. + + -The items are owned by the caller. + + -All memory allocation is done through a heap owned by the caller, who is + responsible for freeing it when done with the vector. + + -When the vector is resized, the old memory area is left allocated since it + uses the same heap as the new memory area, so this is best used for + relatively small or short-lived uses. +*/ + +/******************************************************************** +Create a new vector with the given initial size. */ + +ib_vector_t* +ib_vector_create( +/*=============*/ + /* out: vector */ + mem_heap_t* heap, /* in: heap */ + ulint size); /* in: initial size */ + +/******************************************************************** +Push a new element to the vector, increasing its size if necessary. */ + +void +ib_vector_push( +/*===========*/ + ib_vector_t* vec, /* in: vector */ + void* elem); /* in: data element */ + +/******************************************************************** +Get the number of elements in the vector. */ +UNIV_INLINE +ulint +ib_vector_size( +/*===========*/ + /* out: number of elements in vector */ + ib_vector_t* vec); /* in: vector */ + +/******************************************************************** +Get the n'th element. */ +UNIV_INLINE +void* +ib_vector_get( +/*==========*/ + /* out: n'th element */ + ib_vector_t* vec, /* in: vector */ + ulint n); /* in: element index to get */ + +/* See comment at beginning of file. */ +struct ib_vector_struct { + mem_heap_t* heap; /* heap */ + void** data; /* data elements */ + ulint used; /* number of elements currently used */ + ulint total; /* number of elements allocated */ +}; + +#ifndef UNIV_NONINL +#include "ut0vec.ic" +#endif + +#endif diff --git a/storage/innobase/include/ut0vec.ic b/storage/innobase/include/ut0vec.ic new file mode 100644 index 00000000000..417a17d951f --- /dev/null +++ b/storage/innobase/include/ut0vec.ic @@ -0,0 +1,26 @@ +/******************************************************************** +Get number of elements in vector. */ +UNIV_INLINE +ulint +ib_vector_size( +/*===========*/ + /* out: number of elements in vector */ + ib_vector_t* vec) /* in: vector */ +{ + return(vec->used); +} + +/******************************************************************** +Get n'th element. */ +UNIV_INLINE +void* +ib_vector_get( +/*==========*/ + /* out: n'th element */ + ib_vector_t* vec, /* in: vector */ + ulint n) /* in: element index to get */ +{ + ut_a(n < vec->used); + + return(vec->data[n]); +} diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 1152e0c89ea..34e3296c9bc 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1698,6 +1698,40 @@ lock_sec_rec_some_has_impl_off_kernel( return(row_vers_impl_x_locked_off_kernel(rec, index, offsets)); } +/************************************************************************* +Return approximate number or record locks (bits set in the bitmap) for +this transaction. Since delete-marked records may be removed, the +record count will not be precise. */ + +ulint +lock_number_of_rows_locked( +/*=======================*/ + trx_t* trx) /* in: transaction */ +{ + lock_t* lock; + ulint n_records = 0; + ulint n_bits; + ulint n_bit; + + lock = UT_LIST_GET_FIRST(trx->trx_locks); + + while (lock) { + if (lock_get_type(lock) == LOCK_REC) { + n_bits = lock_rec_get_n_bits(lock); + + for (n_bit = 0; n_bit < n_bits; n_bit++) { + if (lock_rec_get_nth_bit(lock, n_bit)) { + n_records++; + } + } + } + + lock = UT_LIST_GET_NEXT(trx_locks, lock); + } + + return (n_records); +} + /*============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/ /************************************************************************* @@ -2001,7 +2035,8 @@ lock_rec_lock_fast( if (!impl) { lock_rec_create(mode, rec, index, trx); - if (srv_locks_unsafe_for_binlog) { + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { trx_register_new_rec_lock(trx, index); } } @@ -2027,7 +2062,8 @@ lock_rec_lock_fast( if (!lock_rec_get_nth_bit(lock, heap_no)) { lock_rec_set_nth_bit(lock, heap_no); - if (srv_locks_unsafe_for_binlog) { + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { trx_register_new_rec_lock(trx, index); } } @@ -2087,7 +2123,8 @@ lock_rec_lock_slow( err = lock_rec_enqueue_waiting(mode, rec, index, thr); - if (srv_locks_unsafe_for_binlog) { + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { trx_register_new_rec_lock(trx, index); } } else { @@ -2096,7 +2133,8 @@ lock_rec_lock_slow( lock_rec_add_to_queue(LOCK_REC | mode, rec, index, trx); - if (srv_locks_unsafe_for_binlog) { + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { trx_register_new_rec_lock(trx, index); } } @@ -2436,15 +2474,18 @@ lock_rec_inherit_to_gap( lock = lock_rec_get_first(rec); - /* If srv_locks_unsafe_for_binlog is TRUE, we do not want locks set + /* If srv_locks_unsafe_for_binlog is TRUE or session is using + READ COMMITTED isolation level, we do not want locks set by an UPDATE or a DELETE to be inherited as gap type locks. But we DO want S-locks set by a consistency constraint to be inherited also then. */ while (lock != NULL) { if (!lock_rec_get_insert_intention(lock) - && !(srv_locks_unsafe_for_binlog - && lock_get_mode(lock) == LOCK_X)) { + && !((srv_locks_unsafe_for_binlog + || lock->trx->isolation_level == + TRX_ISO_READ_COMMITTED) + && lock_get_mode(lock) == LOCK_X)) { lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock) | LOCK_GAP, @@ -4320,6 +4361,10 @@ loop: (ulong) ut_dulint_get_low(trx->read_view->up_limit_id)); } + fprintf(file, + "Trx has approximately %lu row locks\n", + (ulong) lock_number_of_rows_locked(trx)); + if (trx->que_state == TRX_QUE_LOCK_WAIT) { fprintf(file, "------- TRX HAS BEEN WAITING %lu SEC FOR THIS LOCK TO BE GRANTED:\n", @@ -5167,3 +5212,4 @@ lock_clust_rec_read_check_and_lock_alt( } return(ret); } + diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index f210afe6b5d..2457ca76e72 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -897,9 +897,9 @@ recv_parse_or_apply_log_rec_body( ut_ad(!page || ptr); if (index) { dict_table_t* table = index->table; - mem_heap_free(index->heap); - mutex_free(&(table->autoinc_mutex)); - mem_heap_free(table->heap); + + dict_mem_index_free(index); + dict_mem_table_free(table); } return(ptr); diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c index 86d5beb9c80..86c33a22531 100644 --- a/storage/innobase/mem/mem0dbg.c +++ b/storage/innobase/mem/mem0dbg.c @@ -445,7 +445,7 @@ mem_heap_validate_or_print( && (mem_block_get_len(block) > UNIV_PAGE_SIZE)) { fprintf(stderr, -"InnoDB: Error: mem block %p length %lu > UNIV_PAGE_SIZE\n", block, +"InnoDB: Error: mem block %p length %lu > UNIV_PAGE_SIZE\n", (void*) block, (ulong) mem_block_get_len(block)); /* error */ diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c index 90d3f4fa6b1..5e7c48d3d3d 100644 --- a/storage/innobase/mem/mem0mem.c +++ b/storage/innobase/mem/mem0mem.c @@ -114,6 +114,31 @@ mem_heap_strdup( return(memcpy(mem_heap_alloc(heap, len), str, len)); } +/************************************************************************** +Concatenate two strings and return the result, using a memory heap. */ + +char* +mem_heap_strcat( +/*============*/ + /* out, own: the result */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* s1, /* in: string 1 */ + const char* s2) /* in: string 2 */ +{ + char* s; + ulint s1_len = strlen(s1); + ulint s2_len = strlen(s2); + + s = mem_heap_alloc(heap, s1_len + s2_len + 1); + + memcpy(s, s1, s1_len); + memcpy(s + s1_len, s2, s2_len); + + s[s1_len + s2_len] = '\0'; + + return(s); +} + /******************************************************************* Creates a memory heap block where data can be allocated. */ diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 706c10ac613..eceedcb66b2 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -641,7 +641,7 @@ os_fast_mutex_free( " InnoDB: error: return value %lu when calling\n" "InnoDB: pthread_mutex_destroy().\n", (ulint)ret); fprintf(stderr, -"InnoDB: Byte contents of the pthread mutex at %p:\n", fast_mutex); +"InnoDB: Byte contents of the pthread mutex at %p:\n", (void*) fast_mutex); ut_print_buf(stderr, fast_mutex, sizeof(os_fast_mutex_t)); fprintf(stderr, "\n"); } diff --git a/storage/innobase/pars/lexyy.c b/storage/innobase/pars/lexyy.c index d64ecbbfcbc..bbe78db1613 100644 --- a/storage/innobase/pars/lexyy.c +++ b/storage/innobase/pars/lexyy.c @@ -1,7 +1,7 @@ - -#line 3 "lex.yy.c" - #include "univ.i" +#line 2 "_flex_tmp.c" + +#line 4 "_flex_tmp.c" #define YY_INT_ALIGNED short int @@ -356,8 +356,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 109 -#define YY_END_OF_BUFFER 110 +#define YY_NUM_RULES 116 +#define YY_END_OF_BUFFER 117 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -365,48 +365,52 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[370] = +static yyconst flex_int16_t yy_accept[394] = { 0, - 0, 0, 104, 104, 0, 0, 110, 108, 107, 107, - 99, 3, 88, 94, 97, 95, 92, 96, 108, 98, - 1, 108, 93, 91, 89, 90, 102, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 100, 101, 104, 105, 4, - 5, 107, 83, 103, 2, 1, 84, 85, 87, 86, - 82, 82, 82, 82, 82, 82, 40, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 23, 12, 20, 82, 82, 82, 82, 50, 57, - 82, 9, 82, 82, 82, 82, 82, 82, 82, 82, - - 82, 82, 82, 82, 82, 82, 82, 82, 82, 104, - 105, 105, 106, 4, 5, 2, 8, 41, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 22, 82, 82, 36, - 82, 82, 82, 16, 82, 82, 10, 82, 82, 82, - 13, 82, 82, 82, 82, 82, 76, 82, 82, 82, - 47, 7, 82, 31, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 15, 19, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 42, 82, 82, 25, 82, 82, 82, 34, 82, 82, - - 82, 82, 44, 82, 27, 82, 6, 60, 82, 82, - 82, 38, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 24, 82, 82, 82, 82, 82, 82, 82, 82, - 81, 82, 21, 82, 62, 82, 82, 82, 82, 32, - 82, 82, 82, 82, 82, 82, 82, 26, 61, 18, - 53, 82, 71, 82, 82, 82, 39, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 52, 82, 82, - 82, 82, 82, 82, 35, 28, 75, 14, 82, 79, - 70, 82, 51, 82, 59, 82, 48, 82, 82, 43, - 82, 72, 82, 74, 82, 82, 29, 82, 82, 82, - - 30, 68, 82, 82, 82, 82, 54, 46, 45, 82, - 82, 82, 49, 58, 82, 82, 17, 82, 82, 69, - 77, 82, 82, 73, 82, 64, 82, 82, 82, 82, - 33, 82, 63, 82, 80, 82, 82, 82, 82, 55, - 82, 82, 11, 82, 66, 65, 82, 37, 82, 78, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 67, 82, 82, 82, 82, 82, 82, 56, 0 + 0, 0, 111, 111, 0, 0, 0, 0, 117, 115, + 114, 114, 7, 106, 4, 95, 101, 104, 102, 99, + 103, 115, 105, 1, 115, 100, 98, 96, 97, 109, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 107, 108, + 111, 112, 5, 6, 8, 9, 114, 90, 110, 2, + 1, 3, 91, 92, 94, 93, 89, 89, 89, 89, + 89, 89, 44, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 27, + 16, 24, 89, 89, 89, 89, 54, 61, 89, 13, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 111, 112, 112, + 113, 5, 6, 8, 9, 2, 12, 45, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 26, 89, 89, 89, + 40, 89, 89, 89, 89, 20, 89, 89, 14, 89, + 89, 89, 17, 89, 89, 89, 89, 89, 80, 89, + 89, 89, 51, 11, 89, 35, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 19, 23, 89, 89, 89, 89, 89, 89, 89, 89, + + 89, 89, 89, 46, 89, 89, 29, 89, 87, 89, + 89, 38, 89, 89, 89, 89, 89, 48, 89, 31, + 89, 10, 64, 89, 89, 89, 42, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 28, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 85, 89, 25, 89, + 66, 89, 89, 89, 89, 36, 89, 89, 89, 89, + 89, 89, 89, 30, 65, 22, 89, 57, 89, 75, + 89, 89, 89, 43, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 56, 89, 89, 89, 89, 89, + 89, 89, 39, 32, 79, 18, 89, 83, 74, 89, + + 55, 89, 63, 89, 52, 89, 89, 89, 47, 89, + 76, 89, 78, 89, 89, 33, 89, 89, 89, 34, + 72, 89, 89, 89, 89, 58, 89, 50, 49, 89, + 89, 89, 53, 62, 89, 89, 89, 21, 89, 89, + 73, 81, 89, 89, 77, 89, 68, 89, 89, 89, + 89, 89, 37, 89, 88, 67, 89, 84, 89, 89, + 89, 86, 89, 59, 89, 89, 15, 89, 70, 69, + 89, 41, 89, 82, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 71, 89, 89, 89, 89, 89, + 89, 60, 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -414,17 +418,17 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 4, 1, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 15, 16, 17, - 18, 19, 20, 1, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 30, - 1, 1, 1, 1, 46, 1, 30, 30, 30, 30, - - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 47, 1, 48, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 1, 1, 5, 1, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 17, 18, + 19, 20, 21, 1, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 31, + 1, 1, 1, 1, 47, 1, 31, 31, 31, 31, + + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 48, 1, 49, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -441,209 +445,229 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[49] = +static yyconst flex_int32_t yy_meta[50] = { 0, - 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, - 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1 + 1, 1, 1, 2, 1, 3, 1, 1, 4, 1, + 1, 1, 1, 1, 5, 1, 1, 1, 6, 1, + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 1, 1 } ; -static yyconst flex_int16_t yy_base[376] = +static yyconst flex_int16_t yy_base[403] = { 0, - 0, 0, 390, 389, 391, 390, 394, 399, 47, 49, - 399, 399, 399, 399, 399, 399, 399, 399, 381, 384, - 41, 373, 399, 38, 399, 372, 399, 20, 33, 32, - 46, 29, 44, 0, 46, 49, 42, 60, 351, 65, - 66, 67, 32, 367, 69, 399, 399, 0, 79, 0, - 382, 103, 399, 399, 372, 96, 399, 399, 399, 399, - 0, 361, 70, 357, 349, 347, 0, 360, 77, 80, - 355, 341, 92, 339, 352, 337, 351, 334, 338, 334, - 336, 0, 93, 0, 336, 334, 328, 335, 0, 0, - 341, 341, 324, 87, 98, 339, 93, 88, 330, 104, - - 322, 338, 334, 312, 328, 332, 323, 98, 316, 0, - 122, 131, 399, 0, 348, 338, 0, 0, 326, 321, - 328, 326, 309, 307, 306, 311, 106, 309, 321, 102, - 309, 315, 316, 298, 298, 117, 0, 313, 314, 0, - 301, 308, 118, 122, 305, 295, 304, 297, 294, 302, - 0, 292, 302, 300, 291, 281, 275, 288, 273, 293, - 0, 0, 278, 0, 292, 283, 280, 126, 276, 291, - 270, 272, 277, 277, 269, 272, 267, 0, 0, 279, - 263, 273, 280, 271, 259, 258, 272, 261, 274, 254, - 0, 264, 246, 0, 265, 262, 249, 0, 244, 249, - - 248, 258, 0, 244, 0, 248, 0, 0, 244, 241, - 255, 0, 240, 240, 238, 254, 239, 251, 233, 251, - 246, 0, 241, 241, 227, 226, 226, 240, 239, 238, - 0, 222, 0, 216, 0, 235, 219, 218, 218, 0, - 231, 221, 216, 215, 227, 217, 216, 0, 0, 0, - 0, 209, 0, 223, 219, 205, 0, 219, 220, 203, - 208, 201, 219, 201, 198, 199, 196, 0, 201, 213, - 200, 207, 206, 191, 0, 0, 0, 183, 190, 0, - 0, 187, 0, 186, 0, 200, 0, 201, 188, 0, - 184, 0, 187, 0, 179, 181, 0, 180, 194, 187, - - 0, 0, 190, 193, 175, 190, 0, 0, 0, 171, - 185, 184, 0, 0, 168, 167, 0, 182, 167, 0, - 0, 173, 169, 0, 164, 0, 176, 165, 175, 164, - 0, 151, 0, 171, 0, 155, 149, 155, 146, 0, - 151, 164, 0, 163, 0, 0, 154, 0, 158, 0, - 145, 145, 151, 137, 160, 152, 153, 137, 121, 110, - 0, 122, 129, 120, 117, 113, 105, 0, 399, 160, - 164, 85, 168, 172, 176 + 0, 0, 434, 433, 435, 434, 435, 434, 437, 444, + 48, 50, 444, 444, 444, 444, 444, 444, 444, 444, + 444, 423, 426, 41, 415, 444, 38, 444, 414, 444, + 20, 33, 32, 46, 40, 44, 0, 54, 52, 48, + 60, 393, 65, 66, 74, 27, 409, 69, 444, 444, + 0, 97, 0, 424, 0, 425, 111, 444, 444, 413, + 54, 408, 444, 444, 444, 444, 0, 401, 69, 397, + 389, 387, 0, 400, 79, 82, 395, 381, 94, 379, + 392, 377, 391, 385, 373, 377, 373, 375, 375, 0, + 82, 0, 374, 372, 366, 373, 0, 0, 379, 379, + + 362, 89, 98, 377, 93, 95, 368, 106, 360, 376, + 372, 350, 101, 371, 362, 112, 355, 0, 134, 135, + 444, 0, 387, 0, 388, 376, 0, 0, 364, 359, + 366, 364, 347, 345, 344, 349, 106, 347, 359, 93, + 347, 353, 354, 336, 336, 121, 0, 334, 350, 351, + 0, 338, 347, 344, 119, 126, 341, 331, 340, 333, + 330, 338, 0, 328, 338, 336, 327, 317, 311, 324, + 309, 329, 0, 0, 314, 0, 328, 319, 316, 130, + 312, 319, 326, 305, 307, 312, 312, 304, 307, 302, + 0, 0, 314, 298, 308, 315, 306, 294, 293, 307, + + 296, 309, 289, 0, 299, 281, 0, 300, 0, 297, + 284, 0, 283, 278, 283, 282, 292, 0, 278, 0, + 282, 0, 0, 278, 275, 289, 0, 274, 274, 272, + 288, 273, 285, 267, 285, 280, 0, 275, 275, 261, + 260, 273, 259, 273, 272, 271, 0, 255, 0, 249, + 0, 268, 252, 251, 251, 0, 264, 254, 249, 248, + 260, 250, 249, 0, 0, 0, 253, 0, 241, 0, + 255, 251, 237, 0, 251, 252, 235, 240, 233, 251, + 233, 230, 231, 228, 0, 233, 245, 232, 239, 229, + 237, 222, 0, 0, 0, 214, 221, 0, 0, 218, + + 0, 217, 0, 231, 0, 232, 219, 218, 0, 214, + 0, 217, 0, 209, 211, 0, 210, 224, 217, 0, + 0, 220, 223, 205, 220, 0, 216, 0, 0, 200, + 214, 213, 0, 0, 197, 196, 201, 0, 210, 195, + 0, 0, 201, 197, 0, 192, 0, 204, 204, 192, + 202, 191, 0, 178, 0, 0, 198, 0, 182, 176, + 182, 0, 173, 0, 178, 191, 0, 190, 0, 0, + 181, 0, 185, 0, 172, 172, 178, 164, 187, 175, + 174, 154, 125, 116, 0, 127, 133, 124, 121, 117, + 109, 0, 444, 165, 171, 177, 179, 145, 185, 191, + + 197, 203 } ; -static yyconst flex_int16_t yy_def[376] = +static yyconst flex_int16_t yy_def[403] = { 0, - 369, 1, 370, 370, 371, 371, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 369, 369, 373, 374, 375, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - - 372, 372, 372, 372, 372, 372, 372, 372, 372, 373, - 374, 374, 369, 375, 369, 369, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 0, 369, - 369, 369, 369, 369, 369 + 393, 1, 394, 394, 395, 395, 396, 396, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 397, 393, 393, 393, 393, 393, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 393, 393, + 399, 400, 401, 393, 402, 393, 393, 393, 393, 393, + 393, 397, 393, 393, 393, 393, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 399, 400, 400, + 393, 401, 393, 402, 393, 393, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 0, 393, 393, 393, 393, 393, 393, 393, + + 393, 393 } ; -static yyconst flex_int16_t yy_nxt[448] = +static yyconst flex_int16_t yy_nxt[494] = { 0, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 34, 35, 34, - 34, 36, 34, 37, 38, 39, 34, 40, 41, 42, - 43, 44, 45, 34, 34, 34, 46, 47, 52, 52, - 52, 52, 55, 62, 56, 58, 59, 64, 63, 68, - 76, 65, 77, 69, 66, 105, 70, 106, 78, 71, - 73, 82, 72, 85, 74, 79, 87, 67, 80, 83, - 75, 81, 88, 86, 84, 89, 112, 102, 61, 95, - 98, 113, 118, 90, 103, 91, 108, 92, 96, 97, - - 93, 104, 99, 109, 52, 52, 100, 55, 119, 56, - 101, 124, 126, 127, 131, 152, 142, 125, 154, 160, - 128, 153, 172, 132, 158, 163, 173, 161, 183, 369, - 133, 143, 144, 155, 369, 159, 164, 156, 112, 187, - 188, 194, 200, 113, 184, 195, 202, 223, 224, 368, - 367, 366, 365, 364, 363, 362, 203, 201, 361, 225, - 48, 48, 48, 48, 50, 50, 50, 50, 110, 110, - 360, 110, 111, 111, 111, 111, 114, 359, 114, 114, - 358, 357, 356, 355, 354, 353, 352, 351, 350, 349, - 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, - - 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, - 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, - 318, 317, 316, 315, 314, 313, 312, 311, 310, 309, - 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, - 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, - 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, - 278, 277, 276, 275, 274, 273, 272, 271, 270, 269, - 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, - 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, - 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, - - 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, - 228, 227, 226, 222, 221, 220, 219, 218, 217, 216, - 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, - 205, 204, 199, 198, 197, 196, 193, 192, 191, 190, - 189, 186, 185, 182, 181, 180, 179, 178, 177, 176, - 175, 116, 115, 174, 171, 170, 169, 168, 167, 166, - 165, 162, 157, 151, 150, 149, 148, 147, 146, 145, - 141, 140, 139, 138, 137, 136, 135, 134, 130, 129, - 123, 122, 121, 120, 117, 116, 115, 107, 94, 60, - 57, 54, 53, 369, 51, 51, 49, 49, 7, 369, - - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, + 37, 37, 39, 37, 40, 41, 42, 37, 43, 44, + 45, 46, 47, 48, 37, 37, 37, 49, 50, 57, + 57, 57, 57, 60, 68, 61, 64, 65, 70, 69, + 74, 113, 71, 114, 75, 72, 60, 76, 61, 85, + 77, 79, 82, 78, 83, 80, 86, 93, 73, 87, + 90, 81, 88, 95, 84, 89, 97, 94, 91, 96, + 103, 106, 128, 92, 98, 110, 99, 116, 100, 104, + + 105, 101, 111, 107, 117, 120, 154, 108, 129, 112, + 121, 109, 57, 57, 134, 136, 137, 141, 164, 166, + 135, 155, 156, 138, 165, 170, 142, 172, 175, 196, + 181, 200, 201, 143, 167, 173, 171, 185, 168, 176, + 182, 186, 393, 120, 215, 197, 207, 393, 121, 67, + 208, 217, 238, 239, 392, 391, 390, 389, 388, 216, + 387, 218, 386, 385, 240, 51, 51, 51, 51, 51, + 51, 53, 53, 53, 53, 53, 53, 55, 55, 55, + 55, 55, 55, 62, 62, 118, 118, 118, 384, 118, + 118, 119, 119, 119, 119, 119, 119, 122, 122, 383, + + 122, 122, 122, 124, 382, 124, 124, 124, 124, 381, + 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, + 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, + 360, 359, 358, 357, 356, 355, 354, 353, 352, 351, + 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, + 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, + 330, 329, 328, 327, 326, 325, 324, 323, 322, 321, + 320, 319, 318, 317, 316, 315, 314, 313, 312, 311, + 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, + 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, + + 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, + 280, 279, 278, 277, 276, 275, 274, 273, 272, 271, + 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, + 260, 259, 258, 257, 256, 255, 254, 253, 252, 251, + 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, + 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, + 227, 226, 225, 224, 223, 222, 221, 220, 219, 214, + 213, 212, 211, 210, 209, 206, 205, 204, 203, 202, + 199, 198, 195, 194, 193, 192, 191, 190, 189, 188, + 126, 125, 123, 187, 184, 183, 180, 179, 178, 177, + + 174, 169, 163, 162, 161, 160, 159, 158, 157, 153, + 152, 151, 150, 149, 148, 147, 146, 145, 144, 140, + 139, 133, 132, 131, 130, 127, 393, 126, 125, 123, + 115, 102, 66, 63, 59, 58, 393, 56, 56, 54, + 54, 52, 52, 9, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393 + } ; -static yyconst flex_int16_t yy_chk[448] = +static yyconst flex_int16_t yy_chk[494] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 10, 10, 21, 28, 21, 24, 24, 29, 28, 30, - 32, 29, 32, 30, 29, 43, 30, 43, 33, 30, - 31, 35, 30, 36, 31, 33, 37, 29, 33, 35, - 31, 33, 37, 36, 35, 38, 49, 42, 372, 40, - 41, 49, 63, 38, 42, 38, 45, 38, 40, 40, - - 38, 42, 41, 45, 52, 52, 41, 56, 63, 56, - 41, 69, 70, 70, 73, 94, 83, 69, 95, 98, - 70, 94, 108, 73, 97, 100, 108, 98, 127, 111, - 73, 83, 83, 95, 111, 97, 100, 95, 112, 130, - 130, 136, 143, 112, 127, 136, 144, 168, 168, 367, - 366, 365, 364, 363, 362, 360, 144, 143, 359, 168, - 370, 370, 370, 370, 371, 371, 371, 371, 373, 373, - 358, 373, 374, 374, 374, 374, 375, 357, 375, 375, - 356, 355, 354, 353, 352, 351, 349, 347, 344, 342, - 341, 339, 338, 337, 336, 334, 332, 330, 329, 328, - - 327, 325, 323, 322, 319, 318, 316, 315, 312, 311, - 310, 306, 305, 304, 303, 300, 299, 298, 296, 295, - 293, 291, 289, 288, 286, 284, 282, 279, 278, 274, - 273, 272, 271, 270, 269, 267, 266, 265, 264, 263, - 262, 261, 260, 259, 258, 256, 255, 254, 252, 247, - 246, 245, 244, 243, 242, 241, 239, 238, 237, 236, - 234, 232, 230, 229, 228, 227, 226, 225, 224, 223, - 221, 220, 219, 218, 217, 216, 215, 214, 213, 211, - 210, 209, 206, 204, 202, 201, 200, 199, 197, 196, - 195, 193, 192, 190, 189, 188, 187, 186, 185, 184, - - 183, 182, 181, 180, 177, 176, 175, 174, 173, 172, - 171, 170, 169, 167, 166, 165, 163, 160, 159, 158, - 157, 156, 155, 154, 153, 152, 150, 149, 148, 147, - 146, 145, 142, 141, 139, 138, 135, 134, 133, 132, - 131, 129, 128, 126, 125, 124, 123, 122, 121, 120, - 119, 116, 115, 109, 107, 106, 105, 104, 103, 102, - 101, 99, 96, 93, 92, 91, 88, 87, 86, 85, - 81, 80, 79, 78, 77, 76, 75, 74, 72, 71, - 68, 66, 65, 64, 62, 55, 51, 44, 39, 26, - 22, 20, 19, 7, 6, 5, 4, 3, 369, 369, - - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, + 11, 12, 12, 24, 31, 24, 27, 27, 32, 31, + 33, 46, 32, 46, 33, 32, 61, 33, 61, 36, + 33, 34, 35, 33, 35, 34, 36, 39, 32, 36, + 38, 34, 36, 40, 35, 36, 41, 39, 38, 40, + 43, 44, 69, 38, 41, 45, 41, 48, 41, 43, + + 43, 41, 45, 44, 48, 52, 91, 44, 69, 45, + 52, 44, 57, 57, 75, 76, 76, 79, 102, 103, + 75, 91, 91, 76, 102, 105, 79, 106, 108, 137, + 113, 140, 140, 79, 103, 106, 105, 116, 103, 108, + 113, 116, 119, 120, 155, 137, 146, 119, 120, 398, + 146, 156, 180, 180, 391, 390, 389, 388, 387, 155, + 386, 156, 384, 383, 180, 394, 394, 394, 394, 394, + 394, 395, 395, 395, 395, 395, 395, 396, 396, 396, + 396, 396, 396, 397, 397, 399, 399, 399, 382, 399, + 399, 400, 400, 400, 400, 400, 400, 401, 401, 381, + + 401, 401, 401, 402, 380, 402, 402, 402, 402, 379, + 378, 377, 376, 375, 373, 371, 368, 366, 365, 363, + 361, 360, 359, 357, 354, 352, 351, 350, 349, 348, + 346, 344, 343, 340, 339, 337, 336, 335, 332, 331, + 330, 327, 325, 324, 323, 322, 319, 318, 317, 315, + 314, 312, 310, 308, 307, 306, 304, 302, 300, 297, + 296, 292, 291, 290, 289, 288, 287, 286, 284, 283, + 282, 281, 280, 279, 278, 277, 276, 275, 273, 272, + 271, 269, 267, 263, 262, 261, 260, 259, 258, 257, + 255, 254, 253, 252, 250, 248, 246, 245, 244, 243, + + 242, 241, 240, 239, 238, 236, 235, 234, 233, 232, + 231, 230, 229, 228, 226, 225, 224, 221, 219, 217, + 216, 215, 214, 213, 211, 210, 208, 206, 205, 203, + 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, + 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, + 179, 178, 177, 175, 172, 171, 170, 169, 168, 167, + 166, 165, 164, 162, 161, 160, 159, 158, 157, 154, + 153, 152, 150, 149, 148, 145, 144, 143, 142, 141, + 139, 138, 136, 135, 134, 133, 132, 131, 130, 129, + 126, 125, 123, 117, 115, 114, 112, 111, 110, 109, + + 107, 104, 101, 100, 99, 96, 95, 94, 93, 89, + 88, 87, 86, 85, 84, 83, 82, 81, 80, 78, + 77, 74, 72, 71, 70, 68, 62, 60, 56, 54, + 47, 42, 29, 25, 23, 22, 9, 8, 7, 6, + 5, 4, 3, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393 + } ; static yy_state_type yy_last_accepting_state; @@ -675,34 +699,16 @@ not automatically generate them from pars0grm.y and pars0lex.l. How to make the InnoDB parser and lexer C files: -1. First do - bison -d pars0grm.y - That generates pars0grm.tab.c and pars0grm.tab.h. - -2. Rename pars0grm.tab.c to pars0grm.c and pars0grm.tab.h to pars0grm.h. - -3. Copy pars0grm.h also to /innobase/include - -4. Do - flex pars0lex.l - That generates lex.yy.c. - -5. Rename lex.yy.c to lexyy.c. +1. Run ./make_flex.sh to generate lexer files. -6. Remove the #include of unistd.h from about line 2500 of lexyy.c +2. Run ./make_bison.sh to generate parser files. -7. Add '#include "univ.i"' before #include <stdio.h> in lexyy.c - (Needed for AIX) - -8. Add a type cast to int to the assignment below the comment - 'need more input.' (Removes a warning on Win64) - -These instructions seem to work at least with bison-1.28 and flex-2.5.4 on +These instructions seem to work at least with bison-1.875d and flex-2.5.31 on Linux. *******************************************************/ #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 -#line 56 "pars0lex.l" +#line 38 "pars0lex.l" #define YYSTYPE que_node_t* #include "univ.i" @@ -749,11 +755,13 @@ string_append( -#line 751 "lex.yy.c" + +#line 759 "_flex_tmp.c" #define INITIAL 0 #define comment 1 #define quoted 2 +#define id 3 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -900,10 +908,10 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 106 "pars0lex.l" +#line 91 "pars0lex.l" -#line 905 "lex.yy.c" +#line 914 "_flex_tmp.c" if ( (yy_init) ) { @@ -956,13 +964,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 370 ) + if ( yy_current_state >= 394 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 369 ); + while ( yy_current_state != 393 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -984,7 +992,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 108 "pars0lex.l" +#line 93 "pars0lex.l" { yylval = sym_tab_add_int_lit(pars_sym_tab_global, atoi(yytext)); @@ -993,7 +1001,7 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 114 "pars0lex.l" +#line 99 "pars0lex.l" { ut_error; /* not implemented */ @@ -1002,7 +1010,19 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -#line 120 "pars0lex.l" +#line 105 "pars0lex.l" +{ + ulint type; + + yylval = sym_tab_add_bound_lit(pars_sym_tab_global, + yytext + 1, &type); + + return(type); +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 114 "pars0lex.l" { /* Quoted character string literals are handled in an explicit start state 'quoted'. This state is entered and the buffer for @@ -1013,19 +1033,19 @@ In the state 'quoted', only two actions are possible (defined below). */ stringbuf_len = 0; } YY_BREAK -case 4: -/* rule 4 can match eol */ +case 5: +/* rule 5 can match eol */ YY_RULE_SETUP -#line 129 "pars0lex.l" +#line 123 "pars0lex.l" { /* Got a sequence of characters other than "'": append to string buffer */ string_append(yytext, yyleng); } YY_BREAK -case 5: +case 6: YY_RULE_SETUP -#line 134 "pars0lex.l" +#line 128 "pars0lex.l" { /* Got a sequence of "'" characters: append half of them to string buffer, @@ -1050,18 +1070,69 @@ YY_RULE_SETUP } } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 158 "pars0lex.l" +#line 152 "pars0lex.l" +{ +/* Quoted identifiers are handled in an explicit start state 'id'. +This state is entered and the buffer for the scanned string is emptied +upon encountering a starting quote. + +In the state 'id', only two actions are possible (defined below). */ + BEGIN(id); + stringbuf_len = 0; +} + YY_BREAK +case 8: +/* rule 8 can match eol */ +YY_RULE_SETUP +#line 161 "pars0lex.l" +{ + /* Got a sequence of characters other than '"': + append to string buffer */ + string_append(yytext, yyleng); +} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 166 "pars0lex.l" +{ + /* Got a sequence of '"' characters: + append half of them to string buffer, + as '""' represents a single '"'. + We apply truncating division, + so that '"""' will result in '"'. */ + + string_append(yytext, yyleng / 2); + + /* If we got an odd number of quotes, then the + last quote we got is the terminating quote. + At the end of the string, we return to the + initial start state and report the scanned + identifier. */ + + if (yyleng % 2) { + BEGIN(INITIAL); + yylval = sym_tab_add_id( + pars_sym_tab_global, + (byte*) stringbuf, stringbuf_len); + + return(PARS_ID_TOKEN); + } +} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 191 "pars0lex.l" { yylval = sym_tab_add_null_lit(pars_sym_tab_global); return(PARS_NULL_LIT); } YY_BREAK -case 7: +case 11: YY_RULE_SETUP -#line 164 "pars0lex.l" +#line 197 "pars0lex.l" { /* Implicit cursor name */ yylval = sym_tab_add_str_lit(pars_sym_tab_global, @@ -1069,527 +1140,548 @@ YY_RULE_SETUP return(PARS_SQL_TOKEN); } YY_BREAK -case 8: +case 12: YY_RULE_SETUP -#line 171 "pars0lex.l" +#line 204 "pars0lex.l" { return(PARS_AND_TOKEN); } YY_BREAK -case 9: +case 13: YY_RULE_SETUP -#line 175 "pars0lex.l" +#line 208 "pars0lex.l" { return(PARS_OR_TOKEN); } YY_BREAK -case 10: +case 14: YY_RULE_SETUP -#line 179 "pars0lex.l" +#line 212 "pars0lex.l" { return(PARS_NOT_TOKEN); } YY_BREAK -case 11: +case 15: YY_RULE_SETUP -#line 183 "pars0lex.l" +#line 216 "pars0lex.l" { return(PARS_PROCEDURE_TOKEN); } YY_BREAK -case 12: +case 16: YY_RULE_SETUP -#line 187 "pars0lex.l" +#line 220 "pars0lex.l" { return(PARS_IN_TOKEN); } YY_BREAK -case 13: +case 17: YY_RULE_SETUP -#line 191 "pars0lex.l" +#line 224 "pars0lex.l" { return(PARS_OUT_TOKEN); } YY_BREAK -case 14: +case 18: YY_RULE_SETUP -#line 195 "pars0lex.l" +#line 228 "pars0lex.l" { return(PARS_BINARY_TOKEN); } YY_BREAK -case 15: +case 19: YY_RULE_SETUP -#line 199 "pars0lex.l" +#line 232 "pars0lex.l" { return(PARS_BLOB_TOKEN); } YY_BREAK -case 16: +case 20: YY_RULE_SETUP -#line 203 "pars0lex.l" +#line 236 "pars0lex.l" { return(PARS_INT_TOKEN); } YY_BREAK -case 17: +case 21: YY_RULE_SETUP -#line 207 "pars0lex.l" +#line 240 "pars0lex.l" { return(PARS_INT_TOKEN); } YY_BREAK -case 18: +case 22: YY_RULE_SETUP -#line 211 "pars0lex.l" +#line 244 "pars0lex.l" { return(PARS_FLOAT_TOKEN); } YY_BREAK -case 19: +case 23: YY_RULE_SETUP -#line 215 "pars0lex.l" +#line 248 "pars0lex.l" { return(PARS_CHAR_TOKEN); } YY_BREAK -case 20: +case 24: YY_RULE_SETUP -#line 219 "pars0lex.l" +#line 252 "pars0lex.l" { return(PARS_IS_TOKEN); } YY_BREAK -case 21: +case 25: YY_RULE_SETUP -#line 223 "pars0lex.l" +#line 256 "pars0lex.l" { return(PARS_BEGIN_TOKEN); } YY_BREAK -case 22: +case 26: YY_RULE_SETUP -#line 227 "pars0lex.l" +#line 260 "pars0lex.l" { return(PARS_END_TOKEN); } YY_BREAK -case 23: +case 27: YY_RULE_SETUP -#line 231 "pars0lex.l" +#line 264 "pars0lex.l" { return(PARS_IF_TOKEN); } YY_BREAK -case 24: +case 28: YY_RULE_SETUP -#line 235 "pars0lex.l" +#line 268 "pars0lex.l" { return(PARS_THEN_TOKEN); } YY_BREAK -case 25: +case 29: YY_RULE_SETUP -#line 239 "pars0lex.l" +#line 272 "pars0lex.l" { return(PARS_ELSE_TOKEN); } YY_BREAK -case 26: +case 30: YY_RULE_SETUP -#line 243 "pars0lex.l" +#line 276 "pars0lex.l" { return(PARS_ELSIF_TOKEN); } YY_BREAK -case 27: +case 31: YY_RULE_SETUP -#line 247 "pars0lex.l" +#line 280 "pars0lex.l" { return(PARS_LOOP_TOKEN); } YY_BREAK -case 28: +case 32: YY_RULE_SETUP -#line 251 "pars0lex.l" +#line 284 "pars0lex.l" { return(PARS_WHILE_TOKEN); } YY_BREAK -case 29: +case 33: YY_RULE_SETUP -#line 255 "pars0lex.l" +#line 288 "pars0lex.l" { return(PARS_RETURN_TOKEN); } YY_BREAK -case 30: +case 34: YY_RULE_SETUP -#line 259 "pars0lex.l" +#line 292 "pars0lex.l" { return(PARS_SELECT_TOKEN); } YY_BREAK -case 31: +case 35: YY_RULE_SETUP -#line 263 "pars0lex.l" +#line 296 "pars0lex.l" { return(PARS_SUM_TOKEN); } YY_BREAK -case 32: +case 36: YY_RULE_SETUP -#line 267 "pars0lex.l" +#line 300 "pars0lex.l" { return(PARS_COUNT_TOKEN); } YY_BREAK -case 33: +case 37: YY_RULE_SETUP -#line 271 "pars0lex.l" +#line 304 "pars0lex.l" { return(PARS_DISTINCT_TOKEN); } YY_BREAK -case 34: +case 38: YY_RULE_SETUP -#line 275 "pars0lex.l" +#line 308 "pars0lex.l" { return(PARS_FROM_TOKEN); } YY_BREAK -case 35: +case 39: YY_RULE_SETUP -#line 279 "pars0lex.l" +#line 312 "pars0lex.l" { return(PARS_WHERE_TOKEN); } YY_BREAK -case 36: +case 40: YY_RULE_SETUP -#line 283 "pars0lex.l" +#line 316 "pars0lex.l" { return(PARS_FOR_TOKEN); } YY_BREAK -case 37: +case 41: YY_RULE_SETUP -#line 287 "pars0lex.l" +#line 320 "pars0lex.l" { return(PARS_CONSISTENT_TOKEN); } YY_BREAK -case 38: +case 42: YY_RULE_SETUP -#line 291 "pars0lex.l" +#line 324 "pars0lex.l" { return(PARS_READ_TOKEN); } YY_BREAK -case 39: +case 43: YY_RULE_SETUP -#line 295 "pars0lex.l" +#line 328 "pars0lex.l" { return(PARS_ORDER_TOKEN); } YY_BREAK -case 40: +case 44: YY_RULE_SETUP -#line 299 "pars0lex.l" +#line 332 "pars0lex.l" { return(PARS_BY_TOKEN); } YY_BREAK -case 41: +case 45: YY_RULE_SETUP -#line 303 "pars0lex.l" +#line 336 "pars0lex.l" { return(PARS_ASC_TOKEN); } YY_BREAK -case 42: +case 46: YY_RULE_SETUP -#line 307 "pars0lex.l" +#line 340 "pars0lex.l" { return(PARS_DESC_TOKEN); } YY_BREAK -case 43: +case 47: YY_RULE_SETUP -#line 311 "pars0lex.l" +#line 344 "pars0lex.l" { return(PARS_INSERT_TOKEN); } YY_BREAK -case 44: +case 48: YY_RULE_SETUP -#line 315 "pars0lex.l" +#line 348 "pars0lex.l" { return(PARS_INTO_TOKEN); } YY_BREAK -case 45: +case 49: YY_RULE_SETUP -#line 319 "pars0lex.l" +#line 352 "pars0lex.l" { return(PARS_VALUES_TOKEN); } YY_BREAK -case 46: +case 50: YY_RULE_SETUP -#line 323 "pars0lex.l" +#line 356 "pars0lex.l" { return(PARS_UPDATE_TOKEN); } YY_BREAK -case 47: +case 51: YY_RULE_SETUP -#line 327 "pars0lex.l" +#line 360 "pars0lex.l" { return(PARS_SET_TOKEN); } YY_BREAK -case 48: +case 52: YY_RULE_SETUP -#line 331 "pars0lex.l" +#line 364 "pars0lex.l" { return(PARS_DELETE_TOKEN); } YY_BREAK -case 49: +case 53: YY_RULE_SETUP -#line 335 "pars0lex.l" +#line 368 "pars0lex.l" { return(PARS_CURRENT_TOKEN); } YY_BREAK -case 50: +case 54: YY_RULE_SETUP -#line 339 "pars0lex.l" +#line 372 "pars0lex.l" { return(PARS_OF_TOKEN); } YY_BREAK -case 51: +case 55: YY_RULE_SETUP -#line 343 "pars0lex.l" +#line 376 "pars0lex.l" { return(PARS_CREATE_TOKEN); } YY_BREAK -case 52: +case 56: YY_RULE_SETUP -#line 347 "pars0lex.l" +#line 380 "pars0lex.l" { return(PARS_TABLE_TOKEN); } YY_BREAK -case 53: +case 57: YY_RULE_SETUP -#line 351 "pars0lex.l" +#line 384 "pars0lex.l" { return(PARS_INDEX_TOKEN); } YY_BREAK -case 54: +case 58: YY_RULE_SETUP -#line 355 "pars0lex.l" +#line 388 "pars0lex.l" { return(PARS_UNIQUE_TOKEN); } YY_BREAK -case 55: +case 59: YY_RULE_SETUP -#line 359 "pars0lex.l" +#line 392 "pars0lex.l" { return(PARS_CLUSTERED_TOKEN); } YY_BREAK -case 56: +case 60: YY_RULE_SETUP -#line 363 "pars0lex.l" +#line 396 "pars0lex.l" { return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN); } YY_BREAK -case 57: +case 61: YY_RULE_SETUP -#line 367 "pars0lex.l" +#line 400 "pars0lex.l" { return(PARS_ON_TOKEN); } YY_BREAK -case 58: +case 62: YY_RULE_SETUP -#line 371 "pars0lex.l" +#line 404 "pars0lex.l" { return(PARS_DECLARE_TOKEN); } YY_BREAK -case 59: +case 63: YY_RULE_SETUP -#line 375 "pars0lex.l" +#line 408 "pars0lex.l" { return(PARS_CURSOR_TOKEN); } YY_BREAK -case 60: +case 64: YY_RULE_SETUP -#line 379 "pars0lex.l" +#line 412 "pars0lex.l" { return(PARS_OPEN_TOKEN); } YY_BREAK -case 61: +case 65: YY_RULE_SETUP -#line 383 "pars0lex.l" +#line 416 "pars0lex.l" { return(PARS_FETCH_TOKEN); } YY_BREAK -case 62: +case 66: YY_RULE_SETUP -#line 387 "pars0lex.l" +#line 420 "pars0lex.l" { return(PARS_CLOSE_TOKEN); } YY_BREAK -case 63: +case 67: YY_RULE_SETUP -#line 391 "pars0lex.l" +#line 424 "pars0lex.l" { return(PARS_NOTFOUND_TOKEN); } YY_BREAK -case 64: +case 68: YY_RULE_SETUP -#line 395 "pars0lex.l" +#line 428 "pars0lex.l" { return(PARS_TO_CHAR_TOKEN); } YY_BREAK -case 65: +case 69: YY_RULE_SETUP -#line 399 "pars0lex.l" +#line 432 "pars0lex.l" { return(PARS_TO_NUMBER_TOKEN); } YY_BREAK -case 66: +case 70: YY_RULE_SETUP -#line 403 "pars0lex.l" +#line 436 "pars0lex.l" { return(PARS_TO_BINARY_TOKEN); } YY_BREAK -case 67: +case 71: YY_RULE_SETUP -#line 407 "pars0lex.l" +#line 440 "pars0lex.l" { return(PARS_BINARY_TO_NUMBER_TOKEN); } YY_BREAK -case 68: +case 72: YY_RULE_SETUP -#line 411 "pars0lex.l" +#line 444 "pars0lex.l" { return(PARS_SUBSTR_TOKEN); } YY_BREAK -case 69: +case 73: YY_RULE_SETUP -#line 415 "pars0lex.l" +#line 448 "pars0lex.l" { return(PARS_REPLSTR_TOKEN); } YY_BREAK -case 70: +case 74: YY_RULE_SETUP -#line 419 "pars0lex.l" +#line 452 "pars0lex.l" { return(PARS_CONCAT_TOKEN); } YY_BREAK -case 71: +case 75: YY_RULE_SETUP -#line 423 "pars0lex.l" +#line 456 "pars0lex.l" { return(PARS_INSTR_TOKEN); } YY_BREAK -case 72: +case 76: YY_RULE_SETUP -#line 427 "pars0lex.l" +#line 460 "pars0lex.l" { return(PARS_LENGTH_TOKEN); } YY_BREAK -case 73: +case 77: YY_RULE_SETUP -#line 431 "pars0lex.l" +#line 464 "pars0lex.l" { return(PARS_SYSDATE_TOKEN); } YY_BREAK -case 74: +case 78: YY_RULE_SETUP -#line 435 "pars0lex.l" +#line 468 "pars0lex.l" { return(PARS_PRINTF_TOKEN); } YY_BREAK -case 75: +case 79: YY_RULE_SETUP -#line 439 "pars0lex.l" +#line 472 "pars0lex.l" { return(PARS_ASSERT_TOKEN); } YY_BREAK -case 76: +case 80: YY_RULE_SETUP -#line 443 "pars0lex.l" +#line 476 "pars0lex.l" { return(PARS_RND_TOKEN); } YY_BREAK -case 77: +case 81: YY_RULE_SETUP -#line 447 "pars0lex.l" +#line 480 "pars0lex.l" { return(PARS_RND_STR_TOKEN); } YY_BREAK -case 78: +case 82: YY_RULE_SETUP -#line 451 "pars0lex.l" +#line 484 "pars0lex.l" { return(PARS_ROW_PRINTF_TOKEN); } YY_BREAK -case 79: +case 83: YY_RULE_SETUP -#line 455 "pars0lex.l" +#line 488 "pars0lex.l" { return(PARS_COMMIT_TOKEN); } YY_BREAK -case 80: +case 84: YY_RULE_SETUP -#line 459 "pars0lex.l" +#line 492 "pars0lex.l" { return(PARS_ROLLBACK_TOKEN); } YY_BREAK -case 81: +case 85: YY_RULE_SETUP -#line 463 "pars0lex.l" +#line 496 "pars0lex.l" { return(PARS_WORK_TOKEN); } YY_BREAK -case 82: +case 86: +YY_RULE_SETUP +#line 500 "pars0lex.l" +{ + return(PARS_UNSIGNED_TOKEN); +} + YY_BREAK +case 87: +YY_RULE_SETUP +#line 504 "pars0lex.l" +{ + return(PARS_EXIT_TOKEN); +} + YY_BREAK +case 88: +YY_RULE_SETUP +#line 508 "pars0lex.l" +{ + return(PARS_FUNCTION_TOKEN); +} + YY_BREAK +case 89: YY_RULE_SETUP -#line 467 "pars0lex.l" +#line 512 "pars0lex.l" { yylval = sym_tab_add_id(pars_sym_tab_global, (byte*)yytext, @@ -1597,192 +1689,192 @@ YY_RULE_SETUP return(PARS_ID_TOKEN); } YY_BREAK -case 83: +case 90: YY_RULE_SETUP -#line 474 "pars0lex.l" +#line 519 "pars0lex.l" { return(PARS_DDOT_TOKEN); } YY_BREAK -case 84: +case 91: YY_RULE_SETUP -#line 478 "pars0lex.l" +#line 523 "pars0lex.l" { return(PARS_ASSIGN_TOKEN); } YY_BREAK -case 85: +case 92: YY_RULE_SETUP -#line 482 "pars0lex.l" +#line 527 "pars0lex.l" { return(PARS_LE_TOKEN); } YY_BREAK -case 86: +case 93: YY_RULE_SETUP -#line 486 "pars0lex.l" +#line 531 "pars0lex.l" { return(PARS_GE_TOKEN); } YY_BREAK -case 87: +case 94: YY_RULE_SETUP -#line 490 "pars0lex.l" +#line 535 "pars0lex.l" { return(PARS_NE_TOKEN); } YY_BREAK -case 88: +case 95: YY_RULE_SETUP -#line 494 "pars0lex.l" +#line 539 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 89: +case 96: YY_RULE_SETUP -#line 499 "pars0lex.l" +#line 544 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 90: +case 97: YY_RULE_SETUP -#line 504 "pars0lex.l" +#line 549 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 91: +case 98: YY_RULE_SETUP -#line 509 "pars0lex.l" +#line 554 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 92: +case 99: YY_RULE_SETUP -#line 514 "pars0lex.l" +#line 559 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 93: +case 100: YY_RULE_SETUP -#line 519 "pars0lex.l" +#line 564 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 94: +case 101: YY_RULE_SETUP -#line 524 "pars0lex.l" +#line 569 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 95: +case 102: YY_RULE_SETUP -#line 529 "pars0lex.l" +#line 574 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 96: +case 103: YY_RULE_SETUP -#line 534 "pars0lex.l" +#line 579 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 97: +case 104: YY_RULE_SETUP -#line 539 "pars0lex.l" +#line 584 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 98: +case 105: YY_RULE_SETUP -#line 544 "pars0lex.l" +#line 589 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 99: +case 106: YY_RULE_SETUP -#line 549 "pars0lex.l" +#line 594 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 100: +case 107: YY_RULE_SETUP -#line 554 "pars0lex.l" +#line 599 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 101: +case 108: YY_RULE_SETUP -#line 559 "pars0lex.l" +#line 604 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 102: +case 109: YY_RULE_SETUP -#line 564 "pars0lex.l" +#line 609 "pars0lex.l" { return((int)(*yytext)); } YY_BREAK -case 103: +case 110: YY_RULE_SETUP -#line 569 "pars0lex.l" +#line 614 "pars0lex.l" BEGIN(comment); /* eat up comment */ YY_BREAK -case 104: -/* rule 104 can match eol */ +case 111: +/* rule 111 can match eol */ YY_RULE_SETUP -#line 571 "pars0lex.l" +#line 616 "pars0lex.l" YY_BREAK -case 105: -/* rule 105 can match eol */ +case 112: +/* rule 112 can match eol */ YY_RULE_SETUP -#line 572 "pars0lex.l" +#line 617 "pars0lex.l" YY_BREAK -case 106: +case 113: YY_RULE_SETUP -#line 573 "pars0lex.l" +#line 618 "pars0lex.l" BEGIN(INITIAL); YY_BREAK -case 107: -/* rule 107 can match eol */ +case 114: +/* rule 114 can match eol */ YY_RULE_SETUP -#line 575 "pars0lex.l" +#line 620 "pars0lex.l" /* eat up whitespace */ YY_BREAK -case 108: +case 115: YY_RULE_SETUP -#line 578 "pars0lex.l" +#line 623 "pars0lex.l" { fprintf(stderr,"Unrecognized character: %02x\n", *yytext); @@ -1792,15 +1884,16 @@ YY_RULE_SETUP return(0); } YY_BREAK -case 109: +case 116: YY_RULE_SETUP -#line 587 "pars0lex.l" +#line 632 "pars0lex.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1799 "lex.yy.c" +#line 1892 "_flex_tmp.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(comment): case YY_STATE_EOF(quoted): +case YY_STATE_EOF(id): yyterminate(); case YY_END_OF_BUFFER: @@ -2084,7 +2177,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 370 ) + if ( yy_current_state >= 394 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2112,11 +2205,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 370 ) + if ( yy_current_state >= 394 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 369); + yy_is_jam = (yy_current_state == 393); return yy_is_jam ? 0 : yy_current_state; } @@ -2145,7 +2238,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ - int offset = (int)(yy_c_buf_p - yytext_ptr); + int offset = (int)((yy_c_buf_p) - (yytext_ptr)); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) @@ -2639,7 +2732,7 @@ void yyfree (void * ptr ) #undef YY_DECL_IS_OURS #undef YY_DECL #endif -#line 587 "pars0lex.l" +#line 632 "pars0lex.l" diff --git a/storage/innobase/pars/make_bison.sh b/storage/innobase/pars/make_bison.sh index 43b0322494c..c11456230c4 100755 --- a/storage/innobase/pars/make_bison.sh +++ b/storage/innobase/pars/make_bison.sh @@ -1,7 +1,6 @@ #!/bin/bash # -# regenerate parser from bison input files as documented at the top of -# pars0lex.l. +# generate parser files from bison input files. set -eu diff --git a/storage/innobase/pars/make_flex.sh b/storage/innobase/pars/make_flex.sh new file mode 100755 index 00000000000..c015327bf8c --- /dev/null +++ b/storage/innobase/pars/make_flex.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# +# generate lexer files from flex input files. + +set -eu + +TMPFILE=_flex_tmp.c +OUTFILE=lexyy.c + +flex -o $TMPFILE pars0lex.l + +# AIX needs its includes done in a certain order, so include "univ.i" first +# to be sure we get it right. +echo '#include "univ.i"' > $OUTFILE + +# flex assigns a pointer to an int in one place without a cast, resulting in +# a warning on Win64. this adds the cast. +sed -e 's/int offset = (yy_c_buf_p) - (yytext_ptr);/int offset = (int)((yy_c_buf_p) - (yytext_ptr));/;' < $TMPFILE >> $OUTFILE + +rm $TMPFILE diff --git a/storage/innobase/pars/pars0grm.c b/storage/innobase/pars/pars0grm.c index 3800cdda88e..2cce7cb1c8b 100644 --- a/storage/innobase/pars/pars0grm.c +++ b/storage/innobase/pars/pars0grm.c @@ -56,177 +56,187 @@ PARS_INT_LIT = 258, PARS_FLOAT_LIT = 259, PARS_STR_LIT = 260, - PARS_NULL_LIT = 261, - PARS_ID_TOKEN = 262, - PARS_AND_TOKEN = 263, - PARS_OR_TOKEN = 264, - PARS_NOT_TOKEN = 265, - PARS_GE_TOKEN = 266, - PARS_LE_TOKEN = 267, - PARS_NE_TOKEN = 268, - PARS_PROCEDURE_TOKEN = 269, - PARS_IN_TOKEN = 270, - PARS_OUT_TOKEN = 271, - PARS_BINARY_TOKEN = 272, - PARS_BLOB_TOKEN = 273, - PARS_INT_TOKEN = 274, - PARS_INTEGER_TOKEN = 275, - PARS_FLOAT_TOKEN = 276, - PARS_CHAR_TOKEN = 277, - PARS_IS_TOKEN = 278, - PARS_BEGIN_TOKEN = 279, - PARS_END_TOKEN = 280, - PARS_IF_TOKEN = 281, - PARS_THEN_TOKEN = 282, - PARS_ELSE_TOKEN = 283, - PARS_ELSIF_TOKEN = 284, - PARS_LOOP_TOKEN = 285, - PARS_WHILE_TOKEN = 286, - PARS_RETURN_TOKEN = 287, - PARS_SELECT_TOKEN = 288, - PARS_SUM_TOKEN = 289, - PARS_COUNT_TOKEN = 290, - PARS_DISTINCT_TOKEN = 291, - PARS_FROM_TOKEN = 292, - PARS_WHERE_TOKEN = 293, - PARS_FOR_TOKEN = 294, - PARS_DDOT_TOKEN = 295, - PARS_CONSISTENT_TOKEN = 296, - PARS_READ_TOKEN = 297, - PARS_ORDER_TOKEN = 298, - PARS_BY_TOKEN = 299, - PARS_ASC_TOKEN = 300, - PARS_DESC_TOKEN = 301, - PARS_INSERT_TOKEN = 302, - PARS_INTO_TOKEN = 303, - PARS_VALUES_TOKEN = 304, - PARS_UPDATE_TOKEN = 305, - PARS_SET_TOKEN = 306, - PARS_DELETE_TOKEN = 307, - PARS_CURRENT_TOKEN = 308, - PARS_OF_TOKEN = 309, - PARS_CREATE_TOKEN = 310, - PARS_TABLE_TOKEN = 311, - PARS_INDEX_TOKEN = 312, - PARS_UNIQUE_TOKEN = 313, - PARS_CLUSTERED_TOKEN = 314, - PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 315, - PARS_ON_TOKEN = 316, - PARS_ASSIGN_TOKEN = 317, - PARS_DECLARE_TOKEN = 318, - PARS_CURSOR_TOKEN = 319, - PARS_SQL_TOKEN = 320, - PARS_OPEN_TOKEN = 321, - PARS_FETCH_TOKEN = 322, - PARS_CLOSE_TOKEN = 323, - PARS_NOTFOUND_TOKEN = 324, - PARS_TO_CHAR_TOKEN = 325, - PARS_TO_NUMBER_TOKEN = 326, - PARS_TO_BINARY_TOKEN = 327, - PARS_BINARY_TO_NUMBER_TOKEN = 328, - PARS_SUBSTR_TOKEN = 329, - PARS_REPLSTR_TOKEN = 330, - PARS_CONCAT_TOKEN = 331, - PARS_INSTR_TOKEN = 332, - PARS_LENGTH_TOKEN = 333, - PARS_SYSDATE_TOKEN = 334, - PARS_PRINTF_TOKEN = 335, - PARS_ASSERT_TOKEN = 336, - PARS_RND_TOKEN = 337, - PARS_RND_STR_TOKEN = 338, - PARS_ROW_PRINTF_TOKEN = 339, - PARS_COMMIT_TOKEN = 340, - PARS_ROLLBACK_TOKEN = 341, - PARS_WORK_TOKEN = 342, - NEG = 343 + PARS_FIXBINARY_LIT = 261, + PARS_BLOB_LIT = 262, + PARS_NULL_LIT = 263, + PARS_ID_TOKEN = 264, + PARS_AND_TOKEN = 265, + PARS_OR_TOKEN = 266, + PARS_NOT_TOKEN = 267, + PARS_GE_TOKEN = 268, + PARS_LE_TOKEN = 269, + PARS_NE_TOKEN = 270, + PARS_PROCEDURE_TOKEN = 271, + PARS_IN_TOKEN = 272, + PARS_OUT_TOKEN = 273, + PARS_BINARY_TOKEN = 274, + PARS_BLOB_TOKEN = 275, + PARS_INT_TOKEN = 276, + PARS_INTEGER_TOKEN = 277, + PARS_FLOAT_TOKEN = 278, + PARS_CHAR_TOKEN = 279, + PARS_IS_TOKEN = 280, + PARS_BEGIN_TOKEN = 281, + PARS_END_TOKEN = 282, + PARS_IF_TOKEN = 283, + PARS_THEN_TOKEN = 284, + PARS_ELSE_TOKEN = 285, + PARS_ELSIF_TOKEN = 286, + PARS_LOOP_TOKEN = 287, + PARS_WHILE_TOKEN = 288, + PARS_RETURN_TOKEN = 289, + PARS_SELECT_TOKEN = 290, + PARS_SUM_TOKEN = 291, + PARS_COUNT_TOKEN = 292, + PARS_DISTINCT_TOKEN = 293, + PARS_FROM_TOKEN = 294, + PARS_WHERE_TOKEN = 295, + PARS_FOR_TOKEN = 296, + PARS_DDOT_TOKEN = 297, + PARS_CONSISTENT_TOKEN = 298, + PARS_READ_TOKEN = 299, + PARS_ORDER_TOKEN = 300, + PARS_BY_TOKEN = 301, + PARS_ASC_TOKEN = 302, + PARS_DESC_TOKEN = 303, + PARS_INSERT_TOKEN = 304, + PARS_INTO_TOKEN = 305, + PARS_VALUES_TOKEN = 306, + PARS_UPDATE_TOKEN = 307, + PARS_SET_TOKEN = 308, + PARS_DELETE_TOKEN = 309, + PARS_CURRENT_TOKEN = 310, + PARS_OF_TOKEN = 311, + PARS_CREATE_TOKEN = 312, + PARS_TABLE_TOKEN = 313, + PARS_INDEX_TOKEN = 314, + PARS_UNIQUE_TOKEN = 315, + PARS_CLUSTERED_TOKEN = 316, + PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317, + PARS_ON_TOKEN = 318, + PARS_ASSIGN_TOKEN = 319, + PARS_DECLARE_TOKEN = 320, + PARS_CURSOR_TOKEN = 321, + PARS_SQL_TOKEN = 322, + PARS_OPEN_TOKEN = 323, + PARS_FETCH_TOKEN = 324, + PARS_CLOSE_TOKEN = 325, + PARS_NOTFOUND_TOKEN = 326, + PARS_TO_CHAR_TOKEN = 327, + PARS_TO_NUMBER_TOKEN = 328, + PARS_TO_BINARY_TOKEN = 329, + PARS_BINARY_TO_NUMBER_TOKEN = 330, + PARS_SUBSTR_TOKEN = 331, + PARS_REPLSTR_TOKEN = 332, + PARS_CONCAT_TOKEN = 333, + PARS_INSTR_TOKEN = 334, + PARS_LENGTH_TOKEN = 335, + PARS_SYSDATE_TOKEN = 336, + PARS_PRINTF_TOKEN = 337, + PARS_ASSERT_TOKEN = 338, + PARS_RND_TOKEN = 339, + PARS_RND_STR_TOKEN = 340, + PARS_ROW_PRINTF_TOKEN = 341, + PARS_COMMIT_TOKEN = 342, + PARS_ROLLBACK_TOKEN = 343, + PARS_WORK_TOKEN = 344, + PARS_UNSIGNED_TOKEN = 345, + PARS_EXIT_TOKEN = 346, + PARS_FUNCTION_TOKEN = 347, + NEG = 348 }; #endif #define PARS_INT_LIT 258 #define PARS_FLOAT_LIT 259 #define PARS_STR_LIT 260 -#define PARS_NULL_LIT 261 -#define PARS_ID_TOKEN 262 -#define PARS_AND_TOKEN 263 -#define PARS_OR_TOKEN 264 -#define PARS_NOT_TOKEN 265 -#define PARS_GE_TOKEN 266 -#define PARS_LE_TOKEN 267 -#define PARS_NE_TOKEN 268 -#define PARS_PROCEDURE_TOKEN 269 -#define PARS_IN_TOKEN 270 -#define PARS_OUT_TOKEN 271 -#define PARS_BINARY_TOKEN 272 -#define PARS_BLOB_TOKEN 273 -#define PARS_INT_TOKEN 274 -#define PARS_INTEGER_TOKEN 275 -#define PARS_FLOAT_TOKEN 276 -#define PARS_CHAR_TOKEN 277 -#define PARS_IS_TOKEN 278 -#define PARS_BEGIN_TOKEN 279 -#define PARS_END_TOKEN 280 -#define PARS_IF_TOKEN 281 -#define PARS_THEN_TOKEN 282 -#define PARS_ELSE_TOKEN 283 -#define PARS_ELSIF_TOKEN 284 -#define PARS_LOOP_TOKEN 285 -#define PARS_WHILE_TOKEN 286 -#define PARS_RETURN_TOKEN 287 -#define PARS_SELECT_TOKEN 288 -#define PARS_SUM_TOKEN 289 -#define PARS_COUNT_TOKEN 290 -#define PARS_DISTINCT_TOKEN 291 -#define PARS_FROM_TOKEN 292 -#define PARS_WHERE_TOKEN 293 -#define PARS_FOR_TOKEN 294 -#define PARS_DDOT_TOKEN 295 -#define PARS_CONSISTENT_TOKEN 296 -#define PARS_READ_TOKEN 297 -#define PARS_ORDER_TOKEN 298 -#define PARS_BY_TOKEN 299 -#define PARS_ASC_TOKEN 300 -#define PARS_DESC_TOKEN 301 -#define PARS_INSERT_TOKEN 302 -#define PARS_INTO_TOKEN 303 -#define PARS_VALUES_TOKEN 304 -#define PARS_UPDATE_TOKEN 305 -#define PARS_SET_TOKEN 306 -#define PARS_DELETE_TOKEN 307 -#define PARS_CURRENT_TOKEN 308 -#define PARS_OF_TOKEN 309 -#define PARS_CREATE_TOKEN 310 -#define PARS_TABLE_TOKEN 311 -#define PARS_INDEX_TOKEN 312 -#define PARS_UNIQUE_TOKEN 313 -#define PARS_CLUSTERED_TOKEN 314 -#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 315 -#define PARS_ON_TOKEN 316 -#define PARS_ASSIGN_TOKEN 317 -#define PARS_DECLARE_TOKEN 318 -#define PARS_CURSOR_TOKEN 319 -#define PARS_SQL_TOKEN 320 -#define PARS_OPEN_TOKEN 321 -#define PARS_FETCH_TOKEN 322 -#define PARS_CLOSE_TOKEN 323 -#define PARS_NOTFOUND_TOKEN 324 -#define PARS_TO_CHAR_TOKEN 325 -#define PARS_TO_NUMBER_TOKEN 326 -#define PARS_TO_BINARY_TOKEN 327 -#define PARS_BINARY_TO_NUMBER_TOKEN 328 -#define PARS_SUBSTR_TOKEN 329 -#define PARS_REPLSTR_TOKEN 330 -#define PARS_CONCAT_TOKEN 331 -#define PARS_INSTR_TOKEN 332 -#define PARS_LENGTH_TOKEN 333 -#define PARS_SYSDATE_TOKEN 334 -#define PARS_PRINTF_TOKEN 335 -#define PARS_ASSERT_TOKEN 336 -#define PARS_RND_TOKEN 337 -#define PARS_RND_STR_TOKEN 338 -#define PARS_ROW_PRINTF_TOKEN 339 -#define PARS_COMMIT_TOKEN 340 -#define PARS_ROLLBACK_TOKEN 341 -#define PARS_WORK_TOKEN 342 -#define NEG 343 +#define PARS_FIXBINARY_LIT 261 +#define PARS_BLOB_LIT 262 +#define PARS_NULL_LIT 263 +#define PARS_ID_TOKEN 264 +#define PARS_AND_TOKEN 265 +#define PARS_OR_TOKEN 266 +#define PARS_NOT_TOKEN 267 +#define PARS_GE_TOKEN 268 +#define PARS_LE_TOKEN 269 +#define PARS_NE_TOKEN 270 +#define PARS_PROCEDURE_TOKEN 271 +#define PARS_IN_TOKEN 272 +#define PARS_OUT_TOKEN 273 +#define PARS_BINARY_TOKEN 274 +#define PARS_BLOB_TOKEN 275 +#define PARS_INT_TOKEN 276 +#define PARS_INTEGER_TOKEN 277 +#define PARS_FLOAT_TOKEN 278 +#define PARS_CHAR_TOKEN 279 +#define PARS_IS_TOKEN 280 +#define PARS_BEGIN_TOKEN 281 +#define PARS_END_TOKEN 282 +#define PARS_IF_TOKEN 283 +#define PARS_THEN_TOKEN 284 +#define PARS_ELSE_TOKEN 285 +#define PARS_ELSIF_TOKEN 286 +#define PARS_LOOP_TOKEN 287 +#define PARS_WHILE_TOKEN 288 +#define PARS_RETURN_TOKEN 289 +#define PARS_SELECT_TOKEN 290 +#define PARS_SUM_TOKEN 291 +#define PARS_COUNT_TOKEN 292 +#define PARS_DISTINCT_TOKEN 293 +#define PARS_FROM_TOKEN 294 +#define PARS_WHERE_TOKEN 295 +#define PARS_FOR_TOKEN 296 +#define PARS_DDOT_TOKEN 297 +#define PARS_CONSISTENT_TOKEN 298 +#define PARS_READ_TOKEN 299 +#define PARS_ORDER_TOKEN 300 +#define PARS_BY_TOKEN 301 +#define PARS_ASC_TOKEN 302 +#define PARS_DESC_TOKEN 303 +#define PARS_INSERT_TOKEN 304 +#define PARS_INTO_TOKEN 305 +#define PARS_VALUES_TOKEN 306 +#define PARS_UPDATE_TOKEN 307 +#define PARS_SET_TOKEN 308 +#define PARS_DELETE_TOKEN 309 +#define PARS_CURRENT_TOKEN 310 +#define PARS_OF_TOKEN 311 +#define PARS_CREATE_TOKEN 312 +#define PARS_TABLE_TOKEN 313 +#define PARS_INDEX_TOKEN 314 +#define PARS_UNIQUE_TOKEN 315 +#define PARS_CLUSTERED_TOKEN 316 +#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317 +#define PARS_ON_TOKEN 318 +#define PARS_ASSIGN_TOKEN 319 +#define PARS_DECLARE_TOKEN 320 +#define PARS_CURSOR_TOKEN 321 +#define PARS_SQL_TOKEN 322 +#define PARS_OPEN_TOKEN 323 +#define PARS_FETCH_TOKEN 324 +#define PARS_CLOSE_TOKEN 325 +#define PARS_NOTFOUND_TOKEN 326 +#define PARS_TO_CHAR_TOKEN 327 +#define PARS_TO_NUMBER_TOKEN 328 +#define PARS_TO_BINARY_TOKEN 329 +#define PARS_BINARY_TO_NUMBER_TOKEN 330 +#define PARS_SUBSTR_TOKEN 331 +#define PARS_REPLSTR_TOKEN 332 +#define PARS_CONCAT_TOKEN 333 +#define PARS_INSTR_TOKEN 334 +#define PARS_LENGTH_TOKEN 335 +#define PARS_SYSDATE_TOKEN 336 +#define PARS_PRINTF_TOKEN 337 +#define PARS_ASSERT_TOKEN 338 +#define PARS_RND_TOKEN 339 +#define PARS_RND_STR_TOKEN 340 +#define PARS_ROW_PRINTF_TOKEN 341 +#define PARS_COMMIT_TOKEN 342 +#define PARS_ROLLBACK_TOKEN 343 +#define PARS_WORK_TOKEN 344 +#define PARS_UNSIGNED_TOKEN 345 +#define PARS_EXIT_TOKEN 346 +#define PARS_FUNCTION_TOKEN 347 +#define NEG 348 @@ -279,7 +289,7 @@ typedef int YYSTYPE; /* Line 214 of yacc.c. */ -#line 283 "pars0grm.tab.c" +#line 293 "pars0grm.tab.c" #if ! defined (yyoverflow) || YYERROR_VERBOSE @@ -383,22 +393,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 95 +#define YYFINAL 99 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 734 +#define YYLAST 756 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 104 +#define YYNTOKENS 109 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 64 +#define YYNNTS 69 /* YYNRULES -- Number of rules. */ -#define YYNRULES 164 +#define YYNRULES 175 /* YYNRULES -- Number of states. */ -#define YYNSTATES 321 +#define YYNSTATES 337 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 343 +#define YYMAXUTOK 348 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -409,16 +419,16 @@ static const unsigned char yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, - 98, 99, 93, 92, 101, 91, 2, 94, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, - 89, 88, 90, 100, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 101, 2, 2, + 103, 104, 98, 97, 106, 96, 2, 99, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, + 94, 93, 95, 105, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 102, 2, 103, 2, 2, 2, 2, + 2, 2, 2, 107, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -440,7 +450,7 @@ static const unsigned char yytranslate[] = 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 95 + 85, 86, 87, 88, 89, 90, 91, 92, 100 }; #if YYDEBUG @@ -450,100 +460,105 @@ static const unsigned short int yyprhs[] = { 0, 0, 3, 6, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 53, - 56, 59, 62, 65, 68, 70, 73, 75, 80, 82, - 84, 86, 88, 90, 94, 98, 102, 106, 109, 113, - 117, 121, 125, 129, 133, 137, 141, 145, 148, 152, - 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, - 176, 178, 179, 181, 185, 192, 197, 199, 201, 203, - 205, 209, 210, 212, 216, 217, 219, 223, 225, 230, - 236, 241, 242, 244, 248, 250, 254, 256, 257, 260, - 261, 264, 265, 268, 269, 271, 273, 274, 279, 288, - 292, 298, 301, 305, 307, 311, 316, 321, 324, 327, - 331, 334, 337, 340, 344, 349, 351, 354, 355, 358, - 360, 368, 375, 386, 388, 391, 394, 399, 404, 406, - 410, 411, 415, 416, 419, 420, 422, 430, 432, 436, - 437, 439, 440, 442, 453, 456, 459, 461, 463, 465, - 467, 469, 473, 477, 478, 480, 484, 488, 489, 491, - 494, 501, 502, 504, 507 + 56, 59, 62, 65, 68, 71, 73, 76, 78, 83, + 85, 87, 89, 91, 93, 95, 97, 101, 105, 109, + 113, 116, 120, 124, 128, 132, 136, 140, 144, 148, + 152, 155, 159, 163, 165, 167, 169, 171, 173, 175, + 177, 179, 181, 183, 185, 186, 188, 192, 199, 204, + 206, 208, 210, 214, 216, 220, 221, 223, 227, 228, + 230, 234, 236, 241, 247, 252, 253, 255, 259, 261, + 265, 267, 268, 271, 272, 275, 276, 279, 280, 282, + 284, 285, 290, 299, 303, 309, 312, 316, 318, 322, + 327, 332, 335, 338, 342, 345, 348, 351, 355, 360, + 362, 365, 366, 369, 371, 379, 386, 397, 399, 401, + 404, 407, 412, 417, 423, 425, 429, 430, 434, 435, + 437, 438, 441, 442, 444, 452, 454, 458, 459, 461, + 462, 464, 475, 478, 481, 483, 485, 487, 489, 491, + 495, 499, 500, 502, 506, 510, 511, 513, 516, 523, + 528, 530, 532, 533, 535, 538 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const short int yyrhs[] = { - 105, 0, -1, 167, 97, -1, 110, -1, 111, 97, - -1, 142, 97, -1, 143, 97, -1, 141, 97, -1, - 144, 97, -1, 137, 97, -1, 124, 97, -1, 126, - 97, -1, 136, 97, -1, 134, 97, -1, 135, 97, - -1, 131, 97, -1, 132, 97, -1, 145, 97, -1, - 147, 97, -1, 146, 97, -1, 158, 97, -1, 159, - 97, -1, 153, 97, -1, 157, 97, -1, 105, -1, - 106, 105, -1, 7, -1, 108, 98, 115, 99, -1, - 3, -1, 4, -1, 5, -1, 6, -1, 65, -1, - 107, 92, 107, -1, 107, 91, 107, -1, 107, 93, - 107, -1, 107, 94, 107, -1, 91, 107, -1, 98, - 107, 99, -1, 107, 88, 107, -1, 107, 89, 107, - -1, 107, 90, 107, -1, 107, 11, 107, -1, 107, - 12, 107, -1, 107, 13, 107, -1, 107, 8, 107, - -1, 107, 9, 107, -1, 10, 107, -1, 7, 96, - 69, -1, 65, 96, 69, -1, 70, -1, 71, -1, - 72, -1, 73, -1, 74, -1, 76, -1, 77, -1, - 78, -1, 79, -1, 82, -1, 83, -1, -1, 100, - -1, 109, 101, 100, -1, 102, 7, 98, 109, 99, - 103, -1, 112, 98, 115, 99, -1, 75, -1, 80, - -1, 81, -1, 7, -1, 113, 101, 7, -1, -1, - 7, -1, 114, 101, 7, -1, -1, 107, -1, 115, - 101, 107, -1, 107, -1, 35, 98, 93, 99, -1, - 35, 98, 36, 7, 99, -1, 34, 98, 107, 99, - -1, -1, 116, -1, 117, 101, 116, -1, 93, -1, - 117, 48, 114, -1, 117, -1, -1, 38, 107, -1, - -1, 39, 50, -1, -1, 41, 42, -1, -1, 45, - -1, 46, -1, -1, 43, 44, 7, 122, -1, 33, - 118, 37, 113, 119, 120, 121, 123, -1, 47, 48, - 7, -1, 125, 49, 98, 115, 99, -1, 125, 124, - -1, 7, 88, 107, -1, 127, -1, 128, 101, 127, - -1, 38, 53, 54, 7, -1, 50, 7, 51, 128, - -1, 130, 119, -1, 130, 129, -1, 52, 37, 7, - -1, 133, 119, -1, 133, 129, -1, 84, 124, -1, - 7, 62, 107, -1, 29, 107, 27, 106, -1, 138, - -1, 139, 138, -1, -1, 28, 106, -1, 139, -1, - 26, 107, 27, 106, 140, 25, 26, -1, 31, 107, - 30, 106, 25, 30, -1, 39, 7, 15, 107, 40, - 107, 30, 106, 25, 30, -1, 32, -1, 66, 7, - -1, 68, 7, -1, 67, 7, 48, 114, -1, 7, - 160, 150, 151, -1, 148, -1, 149, 101, 148, -1, - -1, 98, 3, 99, -1, -1, 10, 6, -1, -1, - 60, -1, 55, 56, 7, 98, 149, 99, 152, -1, - 7, -1, 154, 101, 7, -1, -1, 58, -1, -1, - 59, -1, 55, 155, 156, 57, 7, 61, 7, 98, - 154, 99, -1, 85, 87, -1, 86, 87, -1, 19, - -1, 20, -1, 22, -1, 17, -1, 18, -1, 7, - 15, 160, -1, 7, 16, 160, -1, -1, 161, -1, - 162, 101, 161, -1, 7, 160, 97, -1, -1, 163, - -1, 164, 163, -1, 63, 64, 7, 23, 124, 97, - -1, -1, 165, -1, 166, 165, -1, 14, 7, 98, - 162, 99, 23, 164, 166, 24, 106, 25, -1 + 110, 0, -1, 177, 102, -1, 115, -1, 116, 102, + -1, 148, 102, -1, 149, 102, -1, 150, 102, -1, + 147, 102, -1, 151, 102, -1, 143, 102, -1, 130, + 102, -1, 132, 102, -1, 142, 102, -1, 140, 102, + -1, 141, 102, -1, 137, 102, -1, 138, 102, -1, + 152, 102, -1, 154, 102, -1, 153, 102, -1, 166, + 102, -1, 167, 102, -1, 161, 102, -1, 165, 102, + -1, 110, -1, 111, 110, -1, 9, -1, 113, 103, + 121, 104, -1, 3, -1, 4, -1, 5, -1, 6, + -1, 7, -1, 8, -1, 67, -1, 112, 97, 112, + -1, 112, 96, 112, -1, 112, 98, 112, -1, 112, + 99, 112, -1, 96, 112, -1, 103, 112, 104, -1, + 112, 93, 112, -1, 112, 94, 112, -1, 112, 95, + 112, -1, 112, 13, 112, -1, 112, 14, 112, -1, + 112, 15, 112, -1, 112, 10, 112, -1, 112, 11, + 112, -1, 12, 112, -1, 9, 101, 71, -1, 67, + 101, 71, -1, 72, -1, 73, -1, 74, -1, 75, + -1, 76, -1, 78, -1, 79, -1, 80, -1, 81, + -1, 84, -1, 85, -1, -1, 105, -1, 114, 106, + 105, -1, 107, 9, 103, 114, 104, 108, -1, 117, + 103, 121, 104, -1, 77, -1, 82, -1, 83, -1, + 9, 103, 104, -1, 9, -1, 119, 106, 9, -1, + -1, 9, -1, 120, 106, 9, -1, -1, 112, -1, + 121, 106, 112, -1, 112, -1, 37, 103, 98, 104, + -1, 37, 103, 38, 9, 104, -1, 36, 103, 112, + 104, -1, -1, 122, -1, 123, 106, 122, -1, 98, + -1, 123, 50, 120, -1, 123, -1, -1, 40, 112, + -1, -1, 41, 52, -1, -1, 43, 44, -1, -1, + 47, -1, 48, -1, -1, 45, 46, 9, 128, -1, + 35, 124, 39, 119, 125, 126, 127, 129, -1, 49, + 50, 9, -1, 131, 51, 103, 121, 104, -1, 131, + 130, -1, 9, 93, 112, -1, 133, -1, 134, 106, + 133, -1, 40, 55, 56, 9, -1, 52, 9, 53, + 134, -1, 136, 125, -1, 136, 135, -1, 54, 39, + 9, -1, 139, 125, -1, 139, 135, -1, 86, 130, + -1, 9, 64, 112, -1, 31, 112, 29, 111, -1, + 144, -1, 145, 144, -1, -1, 30, 111, -1, 145, + -1, 28, 112, 29, 111, 146, 27, 28, -1, 33, + 112, 32, 111, 27, 32, -1, 41, 9, 17, 112, + 42, 112, 32, 111, 27, 32, -1, 91, -1, 34, + -1, 68, 9, -1, 70, 9, -1, 69, 9, 50, + 120, -1, 69, 9, 50, 118, -1, 9, 168, 157, + 158, 159, -1, 155, -1, 156, 106, 155, -1, -1, + 103, 3, 104, -1, -1, 90, -1, -1, 12, 8, + -1, -1, 62, -1, 57, 58, 9, 103, 156, 104, + 160, -1, 9, -1, 162, 106, 9, -1, -1, 60, + -1, -1, 61, -1, 57, 163, 164, 59, 9, 63, + 9, 103, 162, 104, -1, 87, 89, -1, 88, 89, + -1, 21, -1, 22, -1, 24, -1, 19, -1, 20, + -1, 9, 17, 168, -1, 9, 18, 168, -1, -1, + 169, -1, 170, 106, 169, -1, 9, 168, 102, -1, + -1, 171, -1, 172, 171, -1, 65, 66, 9, 25, + 130, 102, -1, 65, 92, 9, 102, -1, 173, -1, + 174, -1, -1, 175, -1, 176, 175, -1, 16, 9, + 103, 170, 104, 25, 172, 176, 26, 111, 27, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short int yyrline[] = { - 0, 131, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 156, 157, 162, 163, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 187, - 192, 193, 194, 195, 197, 198, 199, 200, 201, 202, - 203, 206, 208, 209, 213, 218, 223, 224, 225, 229, - 230, 235, 236, 237, 242, 243, 244, 248, 249, 254, - 260, 267, 268, 269, 274, 276, 278, 282, 283, 287, - 288, 293, 294, 299, 300, 301, 305, 306, 311, 321, - 326, 328, 333, 337, 338, 343, 349, 356, 361, 366, - 372, 377, 382, 387, 392, 398, 399, 404, 405, 407, - 411, 418, 424, 432, 436, 442, 448, 453, 458, 459, - 464, 465, 470, 471, 477, 478, 484, 490, 491, 496, - 497, 501, 502, 506, 514, 519, 524, 525, 526, 527, - 528, 532, 535, 541, 542, 543, 548, 552, 554, 555, - 559, 564, 566, 567, 571 + 0, 136, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 162, 163, 168, 169, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 195, 200, 201, 202, 203, 205, 206, 207, + 208, 209, 210, 211, 214, 216, 217, 221, 226, 231, + 232, 233, 237, 241, 242, 247, 248, 249, 254, 255, + 256, 260, 261, 266, 272, 279, 280, 281, 286, 288, + 290, 294, 295, 299, 300, 305, 306, 311, 312, 313, + 317, 318, 323, 333, 338, 340, 345, 349, 350, 355, + 361, 368, 373, 378, 384, 389, 394, 399, 404, 410, + 411, 416, 417, 419, 423, 430, 436, 444, 448, 452, + 458, 464, 466, 471, 476, 477, 482, 483, 488, 489, + 495, 496, 502, 503, 509, 515, 516, 521, 522, 526, + 527, 531, 539, 544, 549, 550, 551, 552, 553, 557, + 560, 566, 567, 568, 573, 577, 579, 580, 584, 590, + 595, 596, 599, 601, 602, 606 }; #endif @@ -553,38 +568,40 @@ static const unsigned short int yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "PARS_INT_LIT", "PARS_FLOAT_LIT", - "PARS_STR_LIT", "PARS_NULL_LIT", "PARS_ID_TOKEN", "PARS_AND_TOKEN", - "PARS_OR_TOKEN", "PARS_NOT_TOKEN", "PARS_GE_TOKEN", "PARS_LE_TOKEN", - "PARS_NE_TOKEN", "PARS_PROCEDURE_TOKEN", "PARS_IN_TOKEN", - "PARS_OUT_TOKEN", "PARS_BINARY_TOKEN", "PARS_BLOB_TOKEN", - "PARS_INT_TOKEN", "PARS_INTEGER_TOKEN", "PARS_FLOAT_TOKEN", - "PARS_CHAR_TOKEN", "PARS_IS_TOKEN", "PARS_BEGIN_TOKEN", "PARS_END_TOKEN", - "PARS_IF_TOKEN", "PARS_THEN_TOKEN", "PARS_ELSE_TOKEN", - "PARS_ELSIF_TOKEN", "PARS_LOOP_TOKEN", "PARS_WHILE_TOKEN", - "PARS_RETURN_TOKEN", "PARS_SELECT_TOKEN", "PARS_SUM_TOKEN", - "PARS_COUNT_TOKEN", "PARS_DISTINCT_TOKEN", "PARS_FROM_TOKEN", - "PARS_WHERE_TOKEN", "PARS_FOR_TOKEN", "PARS_DDOT_TOKEN", - "PARS_CONSISTENT_TOKEN", "PARS_READ_TOKEN", "PARS_ORDER_TOKEN", - "PARS_BY_TOKEN", "PARS_ASC_TOKEN", "PARS_DESC_TOKEN", - "PARS_INSERT_TOKEN", "PARS_INTO_TOKEN", "PARS_VALUES_TOKEN", - "PARS_UPDATE_TOKEN", "PARS_SET_TOKEN", "PARS_DELETE_TOKEN", - "PARS_CURRENT_TOKEN", "PARS_OF_TOKEN", "PARS_CREATE_TOKEN", - "PARS_TABLE_TOKEN", "PARS_INDEX_TOKEN", "PARS_UNIQUE_TOKEN", - "PARS_CLUSTERED_TOKEN", "PARS_DOES_NOT_FIT_IN_MEM_TOKEN", - "PARS_ON_TOKEN", "PARS_ASSIGN_TOKEN", "PARS_DECLARE_TOKEN", - "PARS_CURSOR_TOKEN", "PARS_SQL_TOKEN", "PARS_OPEN_TOKEN", - "PARS_FETCH_TOKEN", "PARS_CLOSE_TOKEN", "PARS_NOTFOUND_TOKEN", - "PARS_TO_CHAR_TOKEN", "PARS_TO_NUMBER_TOKEN", "PARS_TO_BINARY_TOKEN", - "PARS_BINARY_TO_NUMBER_TOKEN", "PARS_SUBSTR_TOKEN", "PARS_REPLSTR_TOKEN", - "PARS_CONCAT_TOKEN", "PARS_INSTR_TOKEN", "PARS_LENGTH_TOKEN", - "PARS_SYSDATE_TOKEN", "PARS_PRINTF_TOKEN", "PARS_ASSERT_TOKEN", - "PARS_RND_TOKEN", "PARS_RND_STR_TOKEN", "PARS_ROW_PRINTF_TOKEN", - "PARS_COMMIT_TOKEN", "PARS_ROLLBACK_TOKEN", "PARS_WORK_TOKEN", "'='", - "'<'", "'>'", "'-'", "'+'", "'*'", "'/'", "NEG", "'%'", "';'", "'('", - "')'", "'?'", "','", "'{'", "'}'", "$accept", "statement", - "statement_list", "exp", "function_name", "question_mark_list", - "stored_procedure_call", "predefined_procedure_call", - "predefined_procedure_name", "table_list", "variable_list", "exp_list", + "PARS_STR_LIT", "PARS_FIXBINARY_LIT", "PARS_BLOB_LIT", "PARS_NULL_LIT", + "PARS_ID_TOKEN", "PARS_AND_TOKEN", "PARS_OR_TOKEN", "PARS_NOT_TOKEN", + "PARS_GE_TOKEN", "PARS_LE_TOKEN", "PARS_NE_TOKEN", + "PARS_PROCEDURE_TOKEN", "PARS_IN_TOKEN", "PARS_OUT_TOKEN", + "PARS_BINARY_TOKEN", "PARS_BLOB_TOKEN", "PARS_INT_TOKEN", + "PARS_INTEGER_TOKEN", "PARS_FLOAT_TOKEN", "PARS_CHAR_TOKEN", + "PARS_IS_TOKEN", "PARS_BEGIN_TOKEN", "PARS_END_TOKEN", "PARS_IF_TOKEN", + "PARS_THEN_TOKEN", "PARS_ELSE_TOKEN", "PARS_ELSIF_TOKEN", + "PARS_LOOP_TOKEN", "PARS_WHILE_TOKEN", "PARS_RETURN_TOKEN", + "PARS_SELECT_TOKEN", "PARS_SUM_TOKEN", "PARS_COUNT_TOKEN", + "PARS_DISTINCT_TOKEN", "PARS_FROM_TOKEN", "PARS_WHERE_TOKEN", + "PARS_FOR_TOKEN", "PARS_DDOT_TOKEN", "PARS_CONSISTENT_TOKEN", + "PARS_READ_TOKEN", "PARS_ORDER_TOKEN", "PARS_BY_TOKEN", "PARS_ASC_TOKEN", + "PARS_DESC_TOKEN", "PARS_INSERT_TOKEN", "PARS_INTO_TOKEN", + "PARS_VALUES_TOKEN", "PARS_UPDATE_TOKEN", "PARS_SET_TOKEN", + "PARS_DELETE_TOKEN", "PARS_CURRENT_TOKEN", "PARS_OF_TOKEN", + "PARS_CREATE_TOKEN", "PARS_TABLE_TOKEN", "PARS_INDEX_TOKEN", + "PARS_UNIQUE_TOKEN", "PARS_CLUSTERED_TOKEN", + "PARS_DOES_NOT_FIT_IN_MEM_TOKEN", "PARS_ON_TOKEN", "PARS_ASSIGN_TOKEN", + "PARS_DECLARE_TOKEN", "PARS_CURSOR_TOKEN", "PARS_SQL_TOKEN", + "PARS_OPEN_TOKEN", "PARS_FETCH_TOKEN", "PARS_CLOSE_TOKEN", + "PARS_NOTFOUND_TOKEN", "PARS_TO_CHAR_TOKEN", "PARS_TO_NUMBER_TOKEN", + "PARS_TO_BINARY_TOKEN", "PARS_BINARY_TO_NUMBER_TOKEN", + "PARS_SUBSTR_TOKEN", "PARS_REPLSTR_TOKEN", "PARS_CONCAT_TOKEN", + "PARS_INSTR_TOKEN", "PARS_LENGTH_TOKEN", "PARS_SYSDATE_TOKEN", + "PARS_PRINTF_TOKEN", "PARS_ASSERT_TOKEN", "PARS_RND_TOKEN", + "PARS_RND_STR_TOKEN", "PARS_ROW_PRINTF_TOKEN", "PARS_COMMIT_TOKEN", + "PARS_ROLLBACK_TOKEN", "PARS_WORK_TOKEN", "PARS_UNSIGNED_TOKEN", + "PARS_EXIT_TOKEN", "PARS_FUNCTION_TOKEN", "'='", "'<'", "'>'", "'-'", + "'+'", "'*'", "'/'", "NEG", "'%'", "';'", "'('", "')'", "'?'", "','", + "'{'", "'}'", "$accept", "statement", "statement_list", "exp", + "function_name", "question_mark_list", "stored_procedure_call", + "predefined_procedure_call", "predefined_procedure_name", + "user_function_call", "table_list", "variable_list", "exp_list", "select_item", "select_item_list", "select_list", "search_condition", "for_update_clause", "consistent_read_clause", "order_direction", "order_by_clause", "select_statement", "insert_statement_start", @@ -594,15 +611,16 @@ static const char *const yytname[] = "delete_statement_start", "delete_statement_searched", "delete_statement_positioned", "row_printf_statement", "assignment_statement", "elsif_element", "elsif_list", "else_part", - "if_statement", "while_statement", "for_statement", "return_statement", - "open_cursor_statement", "close_cursor_statement", "fetch_statement", - "column_def", "column_def_list", "opt_column_len", "opt_not_null", - "not_fit_in_memory", "create_table", "column_list", "unique_def", - "clustered_def", "create_index", "commit_statement", - "rollback_statement", "type_name", "parameter_declaration", - "parameter_declaration_list", "variable_declaration", - "variable_declaration_list", "cursor_declaration", "declaration_list", - "procedure_definition", 0 + "if_statement", "while_statement", "for_statement", "exit_statement", + "return_statement", "open_cursor_statement", "close_cursor_statement", + "fetch_statement", "column_def", "column_def_list", "opt_column_len", + "opt_unsigned", "opt_not_null", "not_fit_in_memory", "create_table", + "column_list", "unique_def", "clustered_def", "create_index", + "commit_statement", "rollback_statement", "type_name", + "parameter_declaration", "parameter_declaration_list", + "variable_declaration", "variable_declaration_list", + "cursor_declaration", "function_declaration", "declaration", + "declaration_list", "procedure_definition", 0 }; #endif @@ -619,32 +637,33 @@ static const unsigned short int yytoknum[] = 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 61, 60, - 62, 45, 43, 42, 47, 343, 37, 59, 40, 41, - 63, 44, 123, 125 + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 61, 60, 62, 45, 43, 42, 47, + 348, 37, 59, 40, 41, 63, 44, 123, 125 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { - 0, 104, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 106, 106, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 109, 109, 109, 110, 111, 112, 112, 112, 113, - 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, - 116, 117, 117, 117, 118, 118, 118, 119, 119, 120, - 120, 121, 121, 122, 122, 122, 123, 123, 124, 125, - 126, 126, 127, 128, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 139, 140, 140, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 149, - 150, 150, 151, 151, 152, 152, 153, 154, 154, 155, - 155, 156, 156, 157, 158, 159, 160, 160, 160, 160, - 160, 161, 161, 162, 162, 162, 163, 164, 164, 164, - 165, 166, 166, 166, 167 + 0, 109, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 111, 111, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 114, 114, 114, 115, 116, 117, + 117, 117, 118, 119, 119, 120, 120, 120, 121, 121, + 121, 122, 122, 122, 122, 123, 123, 123, 124, 124, + 124, 125, 125, 126, 126, 127, 127, 128, 128, 128, + 129, 129, 130, 131, 132, 132, 133, 134, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 145, 146, 146, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 154, 155, 156, 156, 157, 157, 158, 158, + 159, 159, 160, 160, 161, 162, 162, 163, 163, 164, + 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, + 169, 170, 170, 170, 171, 172, 172, 172, 173, 174, + 175, 175, 176, 176, 176, 177 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -652,21 +671,22 @@ static const unsigned char yyr2[] = { 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 2, 1, 4, 1, 1, - 1, 1, 1, 3, 3, 3, 3, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 3, 6, 4, 1, 1, 1, 1, - 3, 0, 1, 3, 0, 1, 3, 1, 4, 5, - 4, 0, 1, 3, 1, 3, 1, 0, 2, 0, - 2, 0, 2, 0, 1, 1, 0, 4, 8, 3, - 5, 2, 3, 1, 3, 4, 4, 2, 2, 3, - 2, 2, 2, 3, 4, 1, 2, 0, 2, 1, - 7, 6, 10, 1, 2, 2, 4, 4, 1, 3, - 0, 3, 0, 2, 0, 1, 7, 1, 3, 0, - 1, 0, 1, 10, 2, 2, 1, 1, 1, 1, - 1, 3, 3, 0, 1, 3, 3, 0, 1, 2, - 6, 0, 1, 2, 11 + 2, 2, 2, 2, 2, 1, 2, 1, 4, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 3, 6, 4, 1, + 1, 1, 3, 1, 3, 0, 1, 3, 0, 1, + 3, 1, 4, 5, 4, 0, 1, 3, 1, 3, + 1, 0, 2, 0, 2, 0, 2, 0, 1, 1, + 0, 4, 8, 3, 5, 2, 3, 1, 3, 4, + 4, 2, 2, 3, 2, 2, 2, 3, 4, 1, + 2, 0, 2, 1, 7, 6, 10, 1, 1, 2, + 2, 4, 4, 5, 1, 3, 0, 3, 0, 1, + 0, 2, 0, 1, 7, 1, 3, 0, 1, 0, + 1, 10, 2, 2, 1, 1, 1, 1, 1, 3, + 3, 0, 1, 3, 3, 0, 1, 2, 6, 4, + 1, 1, 0, 1, 2, 11 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -674,103 +694,105 @@ static const unsigned char yyr2[] = means the default is an error. */ static const unsigned char yydefact[] = { - 0, 0, 0, 0, 0, 123, 81, 0, 0, 0, - 0, 139, 0, 0, 0, 66, 67, 68, 0, 0, - 0, 0, 0, 3, 0, 0, 0, 0, 0, 87, - 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 85, 0, 0, 0, + 0, 147, 0, 0, 0, 69, 70, 71, 0, 0, + 0, 127, 0, 0, 3, 0, 0, 0, 0, 0, + 91, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 28, 29, 30, 31, 26, 0, 32, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 0, - 0, 0, 0, 0, 0, 0, 84, 77, 82, 86, - 0, 0, 0, 0, 0, 0, 140, 141, 124, 0, - 125, 112, 144, 145, 0, 1, 4, 74, 10, 0, - 101, 11, 0, 107, 108, 15, 16, 110, 111, 13, - 14, 12, 9, 7, 5, 6, 8, 17, 19, 18, - 22, 23, 20, 21, 2, 113, 153, 0, 47, 0, - 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 74, 0, 0, 0, 71, - 0, 0, 0, 99, 0, 109, 0, 142, 0, 71, - 61, 75, 0, 74, 0, 88, 0, 154, 0, 48, - 49, 38, 45, 46, 42, 43, 44, 24, 117, 39, - 40, 41, 34, 33, 35, 36, 0, 0, 0, 0, - 0, 72, 85, 83, 69, 87, 0, 0, 103, 106, - 0, 0, 126, 62, 0, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 25, 115, 119, 0, 27, - 0, 80, 0, 78, 0, 0, 0, 89, 0, 0, - 0, 0, 128, 0, 0, 0, 0, 76, 100, 105, - 149, 150, 146, 147, 148, 151, 152, 157, 155, 118, - 0, 116, 0, 121, 79, 73, 70, 0, 91, 0, - 102, 104, 130, 134, 0, 0, 64, 63, 0, 158, - 161, 0, 120, 90, 0, 96, 0, 0, 132, 135, - 136, 129, 0, 0, 0, 159, 162, 0, 114, 92, - 0, 98, 0, 0, 0, 127, 0, 156, 0, 0, - 163, 0, 0, 131, 133, 137, 0, 0, 0, 93, - 122, 143, 0, 0, 164, 94, 95, 97, 138, 0, - 160 + 0, 0, 0, 29, 30, 31, 32, 33, 34, 27, + 0, 35, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, + 88, 81, 86, 90, 0, 0, 0, 0, 0, 0, + 148, 149, 129, 0, 130, 116, 152, 153, 0, 1, + 4, 78, 11, 0, 105, 12, 0, 111, 112, 16, + 17, 114, 115, 14, 15, 13, 10, 8, 5, 6, + 7, 9, 18, 20, 19, 23, 24, 21, 22, 2, + 117, 161, 0, 50, 0, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 78, 0, 0, 0, 75, 0, 0, 0, 103, 0, + 113, 0, 150, 0, 75, 64, 79, 0, 78, 0, + 92, 0, 162, 0, 51, 52, 41, 48, 49, 45, + 46, 47, 25, 121, 42, 43, 44, 37, 36, 38, + 39, 0, 0, 0, 0, 0, 76, 89, 87, 73, + 91, 0, 0, 107, 110, 0, 0, 76, 132, 131, + 65, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 119, 123, 0, 28, 0, 84, 0, + 82, 0, 0, 0, 93, 0, 0, 0, 0, 134, + 0, 0, 0, 0, 0, 80, 104, 109, 157, 158, + 154, 155, 156, 159, 160, 165, 163, 122, 0, 120, + 0, 125, 83, 77, 74, 0, 95, 0, 106, 108, + 136, 142, 0, 0, 72, 67, 66, 0, 166, 172, + 0, 124, 94, 0, 100, 0, 0, 138, 143, 144, + 135, 0, 0, 0, 167, 170, 171, 173, 0, 118, + 96, 0, 102, 0, 0, 139, 140, 0, 164, 0, + 0, 0, 174, 0, 0, 137, 0, 133, 145, 0, + 0, 0, 0, 97, 126, 141, 151, 0, 0, 169, + 175, 98, 99, 101, 146, 0, 168 }; /* YYDEFGOTO[NTERM-NUM]. */ static const short int yydefgoto[] = { - -1, 177, 178, 161, 72, 204, 23, 24, 25, 195, - 192, 162, 78, 79, 80, 103, 258, 275, 317, 291, - 26, 27, 28, 198, 199, 104, 29, 30, 31, 32, - 33, 34, 35, 36, 216, 217, 218, 37, 38, 39, - 40, 41, 42, 43, 232, 233, 278, 295, 280, 44, - 306, 87, 158, 45, 46, 47, 245, 167, 168, 269, - 270, 286, 287, 48 + -1, 182, 183, 166, 76, 211, 24, 25, 26, 208, + 200, 197, 167, 82, 83, 84, 107, 266, 284, 333, + 302, 27, 28, 29, 203, 204, 108, 30, 31, 32, + 33, 34, 35, 36, 37, 223, 224, 225, 38, 39, + 40, 41, 42, 43, 44, 45, 239, 240, 287, 306, + 317, 289, 46, 319, 91, 163, 47, 48, 49, 253, + 172, 173, 278, 279, 295, 296, 297, 298, 50 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -205 +#define YYPACT_NINF -209 static const short int yypact[] = { - 454, -48, 30, 521, 521, -205, 12, 42, -18, 46, - -4, -33, 67, 69, 71, -205, -205, -205, 47, -8, - -6, 85, 93, -205, 1, -2, 2, -20, 3, 59, - 5, 7, 59, 24, 27, 28, 31, 32, 33, 39, - 50, 51, 55, 56, 57, 58, 60, 62, 63, 521, - 22, -205, -205, -205, -205, 48, 521, 65, -205, -205, - -205, -205, -205, -205, -205, -205, -205, -205, -205, 521, - 521, 252, 64, 576, 66, 68, -205, 640, -205, -40, - 86, 111, 120, 105, 156, 161, -205, 110, -205, 122, - -205, -205, -205, -205, 73, -205, -205, 521, -205, 74, - -205, -205, 492, -205, -205, -205, -205, -205, -205, -205, - -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, - -205, -205, -205, -205, -205, 640, 167, 106, 309, 107, - 168, 23, 521, 521, 521, 521, 521, 454, 521, 521, - 521, 521, 521, 521, 521, 521, 454, 521, -27, 178, - 204, 179, 521, -205, 181, -205, 91, -205, 134, 178, - 92, 640, -75, 521, 139, 640, 29, -205, -59, -205, - -205, -205, 309, 309, 15, 15, 640, -205, 151, 15, - 15, 15, 25, 25, 168, 168, -58, 284, 535, 187, - 96, -205, 95, -205, -205, -31, 568, 109, -205, 98, - 193, 195, 95, -205, -49, -205, 521, -45, 197, 40, - 40, 189, 167, 454, 521, -205, -205, 186, 191, -205, - 190, -205, 123, -205, 214, 521, 216, 194, 521, 521, - 181, 40, -205, -36, 164, 126, 130, 640, -205, -205, - -205, -205, -205, -205, -205, -205, -205, 227, -205, 454, - 605, -205, 215, -205, -205, -205, -205, 192, 199, 633, - 640, -205, 145, 184, 193, 238, -205, -205, 40, -205, - 4, 454, -205, -205, 205, 203, 454, 245, 240, -205, - -205, -205, 153, 155, 198, -205, -205, -12, 454, -205, - 210, -205, 341, 157, 249, -205, 250, -205, 251, 454, - -205, 259, 229, -205, -205, -205, -26, 244, 398, 26, - -205, -205, 261, 47, -205, -205, -205, -205, -205, 173, - -205 + 578, -30, 40, 256, 256, -209, 19, 44, 7, 55, + 26, -16, 62, 69, 73, -209, -209, -209, 48, -5, + -4, -209, 78, 75, -209, -13, -15, -6, -18, 4, + 67, 6, 12, 67, 17, 18, 21, 29, 30, 32, + 33, 39, 47, 50, 51, 64, 65, 70, 82, 83, + 84, 256, 13, -209, -209, -209, -209, -209, -209, 8, + 256, 20, -209, -209, -209, -209, -209, -209, -209, -209, + -209, -209, -209, 256, 256, 295, 15, 421, 77, 86, + -209, 657, -209, -44, 129, 152, 178, 137, 182, 189, + -209, 142, -209, 154, -209, -209, -209, -209, 104, -209, + -209, 256, -209, 105, -209, -209, 170, -209, -209, -209, + -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, + -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, + 657, 200, 139, 582, 140, 198, 66, 256, 256, 256, + 256, 256, 578, 256, 256, 256, 256, 256, 256, 256, + 256, 578, 256, -31, 205, 121, 206, 256, -209, 207, + -209, 115, -209, 160, 212, 117, 657, -63, 256, 167, + 657, -2, -209, -59, -209, -209, -209, 582, 582, 14, + 14, 657, -209, 330, 14, 14, 14, 3, 3, 198, + 198, -58, 392, 279, 217, 123, -209, 122, -209, -209, + -32, 607, 136, -209, 124, 223, 224, 133, -209, 122, + -209, -52, -209, 256, -46, 229, 16, 16, 214, 200, + 578, 256, -209, -209, 209, 220, -209, 221, -209, 148, + -209, 232, 256, 247, 226, 256, 256, 207, 16, -209, + -43, 195, 165, 162, 166, 657, -209, -209, -209, -209, + -209, -209, -209, -209, -209, 263, -209, 578, 483, -209, + 246, -209, -209, -209, -209, 225, 233, 626, 657, -209, + 172, 216, 223, 270, -209, -209, -209, 16, -209, 1, + 578, -209, -209, 236, 237, 578, 278, 193, -209, -209, + -209, 181, 183, -53, -209, -209, -209, -209, -14, 578, + -209, 240, -209, 454, 184, -209, 275, 282, -209, 286, + 287, 578, -209, 288, 266, -209, 292, -209, -209, -36, + 276, 202, 516, -28, -209, -209, -209, 293, 48, -209, + -209, -209, -209, -209, -209, 210, -209 }; /* YYPGOTO[NTERM-NUM]. */ static const short int yypgoto[] = { - -205, 0, -126, -1, -205, -205, -205, -205, -205, -205, - 112, -124, 135, -205, -205, -28, -205, -205, -205, -205, - -17, -205, -205, 43, -205, 257, -205, -205, -205, -205, - -205, -205, -205, -205, 76, -205, -205, -205, -205, -205, - -205, -205, -205, -205, 8, -205, -205, -205, -205, -205, - -205, -205, -205, -205, -205, -205, -204, 72, -205, 20, - -205, 10, -205, -205 + -209, 0, -130, -1, -209, -209, -209, -209, -209, -209, + -209, 143, -136, 158, -209, -209, -29, -209, -209, -209, + -209, -17, -209, -209, 79, -209, 281, -209, -209, -209, + -209, -209, -209, -209, -209, 91, -209, -209, -209, -209, + -209, -209, -209, -209, -209, -209, 45, -209, -209, -209, + -209, -209, -209, -209, -209, -209, -209, -209, -209, -208, + 99, -209, 41, -209, -209, -209, 23, -209, -209 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -780,197 +802,202 @@ static const short int yypgoto[] = #define YYTABLE_NINF -1 static const unsigned short int yytable[] = { - 22, 91, 71, 73, 107, 77, 246, 225, 149, 189, - 100, 268, 299, 6, 49, 51, 52, 53, 54, 55, - 187, 186, 56, 85, 205, 86, 206, 262, 136, 99, - 82, 132, 133, 84, 134, 135, 136, 50, 136, 207, - 211, 219, 212, 206, 209, 210, 74, 75, 125, 81, - 235, 284, 236, 83, 238, 128, 206, 240, 241, 242, - 243, 150, 244, 263, 283, 264, 190, 284, 130, 131, - 226, 315, 316, 311, 88, 312, 89, 57, 90, 92, - 6, 93, 58, 59, 60, 61, 62, 249, 63, 64, - 65, 66, 94, 95, 67, 68, 97, 102, 96, 98, - 101, 165, 105, 69, 106, 76, 141, 142, 143, 144, - 70, 138, 139, 140, 141, 142, 143, 144, 143, 144, - 126, 109, 171, 151, 110, 111, 152, 153, 112, 113, - 114, 172, 173, 174, 175, 176, 115, 179, 180, 181, - 182, 183, 184, 185, 127, 288, 188, 116, 117, 77, - 292, 196, 118, 119, 120, 121, 154, 122, 1, 123, - 124, 129, 145, 155, 147, 2, 148, 227, 156, 157, - 159, 160, 163, 308, 166, 169, 170, 3, 215, 213, - 214, 136, 4, 5, 6, 191, 194, 215, 197, 200, - 7, 201, 203, 208, 222, 223, 224, 229, 8, 230, - 231, 9, 234, 10, 239, 237, 11, 51, 52, 53, - 54, 55, 247, 250, 56, 214, 252, 12, 13, 14, - 253, 255, 254, 256, 165, 265, 15, 259, 260, 266, - 267, 16, 17, 257, 268, 18, 19, 20, 74, 75, - 274, 272, 273, 277, 279, 282, 290, 289, 293, 215, - 294, 296, 297, 21, 301, 304, 303, 305, 307, 310, - 132, 133, 298, 134, 135, 136, 309, 313, 318, 57, - 320, 202, 281, 261, 58, 59, 60, 61, 62, 137, - 63, 64, 65, 66, 248, 193, 67, 68, 215, 108, - 285, 1, 215, 251, 0, 69, 319, 300, 2, 0, - 0, 0, 70, 0, 0, 0, 0, 0, 215, 220, - 3, 0, 0, 0, 0, 4, 5, 6, 0, 0, - 134, 135, 136, 7, 0, 0, 0, 0, 0, 0, + 23, 95, 75, 77, 111, 81, 154, 194, 232, 254, + 277, 104, 311, 309, 191, 216, 217, 6, 141, 331, + 332, 192, 53, 54, 55, 56, 57, 58, 59, 141, + 270, 60, 214, 103, 51, 248, 249, 250, 251, 310, + 252, 212, 89, 213, 90, 218, 226, 219, 213, 52, + 130, 293, 243, 85, 244, 78, 79, 86, 246, 133, + 213, 271, 155, 272, 87, 88, 293, 195, 326, 292, + 327, 92, 135, 136, 233, 99, 137, 138, 93, 139, + 140, 141, 94, 6, 96, 97, 61, 98, 101, 100, + 257, 62, 63, 64, 65, 66, 102, 67, 68, 69, + 70, 148, 149, 71, 72, 170, 105, 106, 109, 132, + 146, 147, 148, 149, 110, 73, 131, 80, 150, 113, + 114, 134, 74, 115, 53, 54, 55, 56, 57, 58, + 59, 116, 117, 60, 118, 119, 177, 178, 179, 180, + 181, 120, 184, 185, 186, 187, 188, 189, 190, 121, + 299, 193, 122, 123, 81, 303, 201, 78, 79, 143, + 144, 145, 146, 147, 148, 149, 124, 125, 156, 157, + 176, 234, 126, 53, 54, 55, 56, 57, 58, 59, + 152, 322, 60, 222, 127, 128, 129, 158, 61, 153, + 159, 160, 222, 62, 63, 64, 65, 66, 161, 67, + 68, 69, 70, 162, 164, 71, 72, 165, 168, 171, + 174, 175, 245, 141, 196, 199, 202, 73, 205, 206, + 258, 207, 210, 215, 74, 169, 229, 230, 231, 236, + 237, 170, 238, 241, 267, 268, 242, 61, 247, 255, + 221, 263, 62, 63, 64, 65, 66, 260, 67, 68, + 69, 70, 262, 261, 71, 72, 264, 222, 273, 53, + 54, 55, 56, 57, 58, 59, 73, 265, 60, 274, + 275, 276, 277, 74, 281, 286, 283, 282, 288, 291, + 300, 304, 301, 305, 307, 308, 313, 316, 315, 137, + 138, 318, 139, 140, 141, 320, 321, 323, 324, 222, + 325, 328, 334, 222, 329, 137, 138, 209, 139, 140, + 141, 335, 336, 198, 112, 259, 269, 290, 256, 0, + 294, 312, 222, 61, 142, 0, 0, 0, 62, 63, + 64, 65, 66, 0, 67, 68, 69, 70, 0, 1, + 71, 72, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 73, 0, 0, 0, 0, 0, 3, 74, + 220, 221, 0, 4, 5, 6, 0, 0, 0, 0, + 0, 7, 143, 144, 145, 146, 147, 148, 149, 8, + 0, 0, 9, 228, 10, 0, 0, 11, 143, 144, + 145, 146, 147, 148, 149, 0, 0, 0, 12, 13, + 14, 1, 0, 0, 0, 0, 0, 15, 2, 0, + 0, 0, 16, 17, 0, 0, 18, 19, 20, 227, + 3, 21, 0, 0, 0, 4, 5, 6, 0, 0, + 0, 137, 138, 7, 139, 140, 141, 22, 0, 0, 0, 8, 0, 0, 9, 0, 10, 0, 0, 11, - 138, 139, 140, 141, 142, 143, 144, 0, 1, 0, - 12, 13, 14, 0, 0, 2, 0, 0, 0, 15, - 0, 0, 0, 0, 16, 17, 302, 3, 18, 19, - 20, 0, 4, 5, 6, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 21, 0, 8, 0, - 0, 9, 0, 10, 0, 0, 11, 138, 139, 140, - 141, 142, 143, 144, 0, 1, 0, 12, 13, 14, - 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, - 0, 16, 17, 314, 3, 18, 19, 20, 0, 4, + 0, 0, 0, 151, 0, 0, 0, 0, 0, 0, + 12, 13, 14, 1, 0, 0, 0, 0, 0, 15, + 2, 0, 0, 0, 16, 17, 0, 0, 18, 19, + 20, 314, 3, 21, 0, 0, 0, 4, 5, 6, + 0, 0, 0, 137, 138, 7, 139, 140, 141, 22, + 0, 0, 0, 8, 0, 0, 9, 0, 10, 0, + 0, 11, 280, 0, 143, 144, 145, 146, 147, 148, + 149, 0, 12, 13, 14, 1, 0, 0, 0, 0, + 0, 15, 2, 0, 0, 0, 16, 17, 0, 0, + 18, 19, 20, 330, 3, 21, 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 21, 0, 8, 0, 0, 9, 0, - 10, 0, 0, 11, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 12, 13, 14, 0, 2, 0, - 0, 0, 0, 15, 0, 0, 0, 0, 16, 17, - 3, 0, 18, 19, 20, 4, 5, 6, 0, 0, - 0, 0, 0, 7, 0, 51, 52, 53, 54, 55, - 21, 8, 56, 0, 9, 0, 10, 0, 0, 11, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 13, 14, 0, 51, 52, 53, 54, 55, 15, - 0, 56, 0, 0, 16, 17, 0, 0, 18, 19, - 20, 0, 0, 132, 133, 164, 134, 135, 136, 0, - 0, 0, 0, 0, 0, 0, 21, 57, 0, 0, - 0, 0, 58, 59, 60, 61, 62, 0, 63, 64, - 65, 66, 0, 0, 67, 68, 132, 133, 0, 134, - 135, 136, 0, 69, 132, 133, 57, 134, 135, 136, - 70, 58, 59, 60, 61, 62, 0, 63, 64, 65, - 66, 0, 0, 67, 68, 0, 146, 0, 228, 0, - 0, 0, 69, 132, 133, 0, 134, 135, 136, 70, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 144, - 0, 0, 271, 0, 221, 0, 0, 0, 0, 0, - 0, 132, 133, 0, 134, 135, 136, 0, 132, 133, - 0, 134, 135, 136, 0, 0, 138, 139, 140, 141, - 142, 143, 144, 276, 138, 139, 140, 141, 142, 143, - 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 22, 0, 0, 0, 8, 0, 0, 9, 0, + 10, 0, 0, 11, 0, 0, 143, 144, 145, 146, + 147, 148, 149, 0, 12, 13, 14, 1, 0, 0, + 0, 0, 0, 15, 2, 139, 140, 141, 16, 17, + 0, 0, 18, 19, 20, 0, 3, 21, 0, 0, + 0, 4, 5, 6, 0, 0, 0, 137, 138, 7, + 139, 140, 141, 22, 0, 0, 0, 8, 0, 0, + 9, 0, 10, 0, 0, 11, 137, 138, 0, 139, + 140, 141, 0, 0, 0, 0, 12, 13, 14, 235, + 0, 0, 0, 0, 0, 15, 0, 0, 285, 0, + 16, 17, 0, 0, 18, 19, 20, 137, 138, 21, + 139, 140, 141, 0, 0, 143, 144, 145, 146, 147, + 148, 149, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 144, + 143, 144, 145, 146, 147, 148, 149, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, + 144, 145, 146, 147, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 138, 139, 140, 141, 142, 143, 144, 138, 139, - 140, 141, 142, 143, 144 + 143, 144, 145, 146, 147, 148, 149 }; static const short int yycheck[] = { - 0, 18, 3, 4, 32, 6, 210, 38, 48, 36, - 27, 7, 24, 33, 62, 3, 4, 5, 6, 7, - 146, 145, 10, 56, 99, 58, 101, 231, 13, 49, - 48, 8, 9, 37, 11, 12, 13, 7, 13, 163, - 99, 99, 101, 101, 15, 16, 34, 35, 49, 7, - 99, 63, 101, 7, 99, 56, 101, 17, 18, 19, - 20, 101, 22, 99, 268, 101, 93, 63, 69, 70, - 101, 45, 46, 99, 7, 101, 7, 65, 7, 87, - 33, 87, 70, 71, 72, 73, 74, 213, 76, 77, - 78, 79, 7, 0, 82, 83, 98, 38, 97, 97, - 97, 102, 97, 91, 97, 93, 91, 92, 93, 94, - 98, 88, 89, 90, 91, 92, 93, 94, 93, 94, - 98, 97, 99, 37, 97, 97, 15, 7, 97, 97, - 97, 132, 133, 134, 135, 136, 97, 138, 139, 140, - 141, 142, 143, 144, 96, 271, 147, 97, 97, 150, - 276, 152, 97, 97, 97, 97, 51, 97, 7, 97, - 97, 96, 98, 7, 98, 14, 98, 195, 7, 59, - 48, 98, 98, 299, 7, 69, 69, 26, 178, 28, - 29, 13, 31, 32, 33, 7, 7, 187, 7, 98, - 39, 57, 100, 54, 7, 99, 101, 88, 47, 101, - 7, 50, 7, 52, 7, 206, 55, 3, 4, 5, - 6, 7, 23, 214, 10, 29, 25, 66, 67, 68, - 30, 7, 99, 7, 225, 61, 75, 228, 229, 103, - 100, 80, 81, 39, 7, 84, 85, 86, 34, 35, - 41, 26, 50, 98, 60, 7, 43, 42, 3, 249, - 10, 98, 97, 102, 44, 6, 99, 7, 7, 30, - 8, 9, 64, 11, 12, 13, 7, 23, 7, 65, - 97, 159, 264, 230, 70, 71, 72, 73, 74, 27, - 76, 77, 78, 79, 212, 150, 82, 83, 288, 32, - 270, 7, 292, 217, -1, 91, 313, 287, 14, -1, - -1, -1, 98, -1, -1, -1, -1, -1, 308, 25, - 26, -1, -1, -1, -1, 31, 32, 33, -1, -1, - 11, 12, 13, 39, -1, -1, -1, -1, -1, -1, - -1, 47, -1, -1, 50, -1, 52, -1, -1, 55, - 88, 89, 90, 91, 92, 93, 94, -1, 7, -1, - 66, 67, 68, -1, -1, 14, -1, -1, -1, 75, - -1, -1, -1, -1, 80, 81, 25, 26, 84, 85, - 86, -1, 31, 32, 33, -1, -1, -1, -1, -1, - 39, -1, -1, -1, -1, -1, 102, -1, 47, -1, - -1, 50, -1, 52, -1, -1, 55, 88, 89, 90, - 91, 92, 93, 94, -1, 7, -1, 66, 67, 68, - -1, -1, 14, -1, -1, -1, 75, -1, -1, -1, - -1, 80, 81, 25, 26, 84, 85, 86, -1, 31, - 32, 33, -1, -1, -1, -1, -1, 39, -1, -1, - -1, -1, -1, 102, -1, 47, -1, -1, 50, -1, - 52, -1, -1, 55, -1, -1, -1, -1, -1, -1, - -1, 7, -1, -1, 66, 67, 68, -1, 14, -1, - -1, -1, -1, 75, -1, -1, -1, -1, 80, 81, - 26, -1, 84, 85, 86, 31, 32, 33, -1, -1, - -1, -1, -1, 39, -1, 3, 4, 5, 6, 7, - 102, 47, 10, -1, 50, -1, 52, -1, -1, 55, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 66, 67, 68, -1, 3, 4, 5, 6, 7, 75, - -1, 10, -1, -1, 80, 81, -1, -1, 84, 85, - 86, -1, -1, 8, 9, 53, 11, 12, 13, -1, - -1, -1, -1, -1, -1, -1, 102, 65, -1, -1, - -1, -1, 70, 71, 72, 73, 74, -1, 76, 77, - 78, 79, -1, -1, 82, 83, 8, 9, -1, 11, - 12, 13, -1, 91, 8, 9, 65, 11, 12, 13, - 98, 70, 71, 72, 73, 74, -1, 76, 77, 78, - 79, -1, -1, 82, 83, -1, 30, -1, 40, -1, - -1, -1, 91, 8, 9, -1, 11, 12, 13, 98, - -1, -1, -1, 88, 89, 90, 91, 92, 93, 94, - -1, -1, 27, -1, 99, -1, -1, -1, -1, -1, - -1, 8, 9, -1, 11, 12, 13, -1, 8, 9, - -1, 11, 12, 13, -1, -1, 88, 89, 90, 91, - 92, 93, 94, 30, 88, 89, 90, 91, 92, 93, - 94, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 18, 3, 4, 33, 6, 50, 38, 40, 217, + 9, 28, 26, 66, 150, 17, 18, 35, 15, 47, + 48, 151, 3, 4, 5, 6, 7, 8, 9, 15, + 238, 12, 168, 51, 64, 19, 20, 21, 22, 92, + 24, 104, 58, 106, 60, 104, 104, 106, 106, 9, + 51, 65, 104, 9, 106, 36, 37, 50, 104, 60, + 106, 104, 106, 106, 9, 39, 65, 98, 104, 277, + 106, 9, 73, 74, 106, 0, 10, 11, 9, 13, + 14, 15, 9, 35, 89, 89, 67, 9, 103, 102, + 220, 72, 73, 74, 75, 76, 102, 78, 79, 80, + 81, 98, 99, 84, 85, 106, 102, 40, 102, 101, + 96, 97, 98, 99, 102, 96, 103, 98, 103, 102, + 102, 101, 103, 102, 3, 4, 5, 6, 7, 8, + 9, 102, 102, 12, 102, 102, 137, 138, 139, 140, + 141, 102, 143, 144, 145, 146, 147, 148, 149, 102, + 280, 152, 102, 102, 155, 285, 157, 36, 37, 93, + 94, 95, 96, 97, 98, 99, 102, 102, 39, 17, + 104, 200, 102, 3, 4, 5, 6, 7, 8, 9, + 103, 311, 12, 183, 102, 102, 102, 9, 67, 103, + 53, 9, 192, 72, 73, 74, 75, 76, 9, 78, + 79, 80, 81, 61, 50, 84, 85, 103, 103, 9, + 71, 71, 213, 15, 9, 9, 9, 96, 103, 59, + 221, 9, 105, 56, 103, 55, 9, 104, 106, 93, + 106, 232, 9, 9, 235, 236, 103, 67, 9, 25, + 31, 9, 72, 73, 74, 75, 76, 27, 78, 79, + 80, 81, 104, 32, 84, 85, 9, 257, 63, 3, + 4, 5, 6, 7, 8, 9, 96, 41, 12, 104, + 108, 105, 9, 103, 28, 103, 43, 52, 62, 9, + 44, 3, 45, 90, 103, 102, 46, 12, 104, 10, + 11, 9, 13, 14, 15, 9, 9, 9, 32, 299, + 8, 25, 9, 303, 102, 10, 11, 164, 13, 14, + 15, 328, 102, 155, 33, 224, 237, 272, 219, -1, + 279, 298, 322, 67, 29, -1, -1, -1, 72, 73, + 74, 75, 76, -1, 78, 79, 80, 81, -1, 9, + 84, 85, -1, -1, -1, -1, 16, -1, -1, -1, + -1, -1, 96, -1, -1, -1, -1, -1, 28, 103, + 30, 31, -1, 33, 34, 35, -1, -1, -1, -1, + -1, 41, 93, 94, 95, 96, 97, 98, 99, 49, + -1, -1, 52, 104, 54, -1, -1, 57, 93, 94, + 95, 96, 97, 98, 99, -1, -1, -1, 68, 69, + 70, 9, -1, -1, -1, -1, -1, 77, 16, -1, + -1, -1, 82, 83, -1, -1, 86, 87, 88, 27, + 28, 91, -1, -1, -1, 33, 34, 35, -1, -1, + -1, 10, 11, 41, 13, 14, 15, 107, -1, -1, + -1, 49, -1, -1, 52, -1, 54, -1, -1, 57, + -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, + 68, 69, 70, 9, -1, -1, -1, -1, -1, 77, + 16, -1, -1, -1, 82, 83, -1, -1, 86, 87, + 88, 27, 28, 91, -1, -1, -1, 33, 34, 35, + -1, -1, -1, 10, 11, 41, 13, 14, 15, 107, + -1, -1, -1, 49, -1, -1, 52, -1, 54, -1, + -1, 57, 29, -1, 93, 94, 95, 96, 97, 98, + 99, -1, 68, 69, 70, 9, -1, -1, -1, -1, + -1, 77, 16, -1, -1, -1, 82, 83, -1, -1, + 86, 87, 88, 27, 28, 91, -1, -1, -1, 33, + 34, 35, -1, -1, -1, -1, -1, 41, -1, -1, + -1, 107, -1, -1, -1, 49, -1, -1, 52, -1, + 54, -1, -1, 57, -1, -1, 93, 94, 95, 96, + 97, 98, 99, -1, 68, 69, 70, 9, -1, -1, + -1, -1, -1, 77, 16, 13, 14, 15, 82, 83, + -1, -1, 86, 87, 88, -1, 28, 91, -1, -1, + -1, 33, 34, 35, -1, -1, -1, 10, 11, 41, + 13, 14, 15, 107, -1, -1, -1, 49, -1, -1, + 52, -1, 54, -1, -1, 57, 10, 11, -1, 13, + 14, 15, -1, -1, -1, -1, 68, 69, 70, 42, + -1, -1, -1, -1, -1, 77, -1, -1, 32, -1, + 82, 83, -1, -1, 86, 87, 88, 10, 11, 91, + 13, 14, 15, -1, -1, 93, 94, 95, 96, 97, + 98, 99, -1, -1, -1, 107, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 88, 89, 90, 91, 92, 93, 94, + 93, 94, 95, 96, 97, 98, 99, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, + 94, 95, 96, 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 88, 89, 90, 91, 92, 93, 94, 88, 89, - 90, 91, 92, 93, 94 + 93, 94, 95, 96, 97, 98, 99 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { - 0, 7, 14, 26, 31, 32, 33, 39, 47, 50, - 52, 55, 66, 67, 68, 75, 80, 81, 84, 85, - 86, 102, 105, 110, 111, 112, 124, 125, 126, 130, - 131, 132, 133, 134, 135, 136, 137, 141, 142, 143, - 144, 145, 146, 147, 153, 157, 158, 159, 167, 62, - 7, 3, 4, 5, 6, 7, 10, 65, 70, 71, - 72, 73, 74, 76, 77, 78, 79, 82, 83, 91, - 98, 107, 108, 107, 34, 35, 93, 107, 116, 117, - 118, 7, 48, 7, 37, 56, 58, 155, 7, 7, - 7, 124, 87, 87, 7, 0, 97, 98, 97, 49, - 124, 97, 38, 119, 129, 97, 97, 119, 129, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 107, 98, 96, 107, 96, - 107, 107, 8, 9, 11, 12, 13, 27, 88, 89, - 90, 91, 92, 93, 94, 98, 30, 98, 98, 48, - 101, 37, 15, 7, 51, 7, 7, 59, 156, 48, - 98, 107, 115, 98, 53, 107, 7, 161, 162, 69, - 69, 99, 107, 107, 107, 107, 107, 105, 106, 107, - 107, 107, 107, 107, 107, 107, 115, 106, 107, 36, - 93, 7, 114, 116, 7, 113, 107, 7, 127, 128, - 98, 57, 114, 100, 109, 99, 101, 115, 54, 15, - 16, 99, 101, 28, 29, 105, 138, 139, 140, 99, - 25, 99, 7, 99, 101, 38, 101, 119, 40, 88, - 101, 7, 148, 149, 7, 99, 101, 107, 99, 7, - 17, 18, 19, 20, 22, 160, 160, 23, 161, 106, - 107, 138, 25, 30, 99, 7, 7, 39, 120, 107, - 107, 127, 160, 99, 101, 61, 103, 100, 7, 163, - 164, 27, 26, 50, 41, 121, 30, 98, 150, 60, - 152, 148, 7, 160, 63, 163, 165, 166, 106, 42, - 43, 123, 106, 3, 10, 151, 98, 97, 64, 24, - 165, 44, 25, 99, 6, 7, 154, 7, 106, 7, - 30, 99, 101, 23, 25, 45, 46, 122, 7, 124, - 97 + 0, 9, 16, 28, 33, 34, 35, 41, 49, 52, + 54, 57, 68, 69, 70, 77, 82, 83, 86, 87, + 88, 91, 107, 110, 115, 116, 117, 130, 131, 132, + 136, 137, 138, 139, 140, 141, 142, 143, 147, 148, + 149, 150, 151, 152, 153, 154, 161, 165, 166, 167, + 177, 64, 9, 3, 4, 5, 6, 7, 8, 9, + 12, 67, 72, 73, 74, 75, 76, 78, 79, 80, + 81, 84, 85, 96, 103, 112, 113, 112, 36, 37, + 98, 112, 122, 123, 124, 9, 50, 9, 39, 58, + 60, 163, 9, 9, 9, 130, 89, 89, 9, 0, + 102, 103, 102, 51, 130, 102, 40, 125, 135, 102, + 102, 125, 135, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 112, 103, 101, 112, 101, 112, 112, 10, 11, 13, + 14, 15, 29, 93, 94, 95, 96, 97, 98, 99, + 103, 32, 103, 103, 50, 106, 39, 17, 9, 53, + 9, 9, 61, 164, 50, 103, 112, 121, 103, 55, + 112, 9, 169, 170, 71, 71, 104, 112, 112, 112, + 112, 112, 110, 111, 112, 112, 112, 112, 112, 112, + 112, 121, 111, 112, 38, 98, 9, 120, 122, 9, + 119, 112, 9, 133, 134, 103, 59, 9, 118, 120, + 105, 114, 104, 106, 121, 56, 17, 18, 104, 106, + 30, 31, 110, 144, 145, 146, 104, 27, 104, 9, + 104, 106, 40, 106, 125, 42, 93, 106, 9, 155, + 156, 9, 103, 104, 106, 112, 104, 9, 19, 20, + 21, 22, 24, 168, 168, 25, 169, 111, 112, 144, + 27, 32, 104, 9, 9, 41, 126, 112, 112, 133, + 168, 104, 106, 63, 104, 108, 105, 9, 171, 172, + 29, 28, 52, 43, 127, 32, 103, 157, 62, 160, + 155, 9, 168, 65, 171, 173, 174, 175, 176, 111, + 44, 45, 129, 111, 3, 90, 158, 103, 102, 66, + 92, 26, 175, 46, 27, 104, 12, 159, 9, 162, + 9, 9, 111, 9, 32, 8, 104, 106, 25, 102, + 27, 47, 48, 128, 9, 130, 102 }; #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) @@ -1581,271 +1608,286 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 24: -#line 156 "pars0grm.y" + case 25: +#line 162 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 25: -#line 158 "pars0grm.y" - { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); ;} - break; - case 26: -#line 162 "pars0grm.y" - { yyval = yyvsp[0];;} +#line 164 "pars0grm.y" + { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); ;} break; case 27: -#line 164 "pars0grm.y" - { yyval = pars_func(yyvsp[-3], yyvsp[-1]); ;} +#line 168 "pars0grm.y" + { yyval = yyvsp[0];;} break; case 28: -#line 165 "pars0grm.y" - { yyval = yyvsp[0];;} +#line 170 "pars0grm.y" + { yyval = pars_func(yyvsp[-3], yyvsp[-1]); ;} break; case 29: -#line 166 "pars0grm.y" +#line 171 "pars0grm.y" { yyval = yyvsp[0];;} break; case 30: -#line 167 "pars0grm.y" +#line 172 "pars0grm.y" { yyval = yyvsp[0];;} break; case 31: -#line 168 "pars0grm.y" +#line 173 "pars0grm.y" { yyval = yyvsp[0];;} break; case 32: -#line 169 "pars0grm.y" +#line 174 "pars0grm.y" { yyval = yyvsp[0];;} break; case 33: -#line 170 "pars0grm.y" - { yyval = pars_op('+', yyvsp[-2], yyvsp[0]); ;} +#line 175 "pars0grm.y" + { yyval = yyvsp[0];;} break; case 34: -#line 171 "pars0grm.y" - { yyval = pars_op('-', yyvsp[-2], yyvsp[0]); ;} +#line 176 "pars0grm.y" + { yyval = yyvsp[0];;} break; case 35: -#line 172 "pars0grm.y" - { yyval = pars_op('*', yyvsp[-2], yyvsp[0]); ;} +#line 177 "pars0grm.y" + { yyval = yyvsp[0];;} break; case 36: -#line 173 "pars0grm.y" - { yyval = pars_op('/', yyvsp[-2], yyvsp[0]); ;} +#line 178 "pars0grm.y" + { yyval = pars_op('+', yyvsp[-2], yyvsp[0]); ;} break; case 37: -#line 174 "pars0grm.y" - { yyval = pars_op('-', yyvsp[0], NULL); ;} +#line 179 "pars0grm.y" + { yyval = pars_op('-', yyvsp[-2], yyvsp[0]); ;} break; case 38: -#line 175 "pars0grm.y" - { yyval = yyvsp[-1]; ;} +#line 180 "pars0grm.y" + { yyval = pars_op('*', yyvsp[-2], yyvsp[0]); ;} break; case 39: -#line 176 "pars0grm.y" - { yyval = pars_op('=', yyvsp[-2], yyvsp[0]); ;} +#line 181 "pars0grm.y" + { yyval = pars_op('/', yyvsp[-2], yyvsp[0]); ;} break; case 40: -#line 177 "pars0grm.y" - { yyval = pars_op('<', yyvsp[-2], yyvsp[0]); ;} +#line 182 "pars0grm.y" + { yyval = pars_op('-', yyvsp[0], NULL); ;} break; case 41: -#line 178 "pars0grm.y" - { yyval = pars_op('>', yyvsp[-2], yyvsp[0]); ;} +#line 183 "pars0grm.y" + { yyval = yyvsp[-1]; ;} break; case 42: -#line 179 "pars0grm.y" - { yyval = pars_op(PARS_GE_TOKEN, yyvsp[-2], yyvsp[0]); ;} +#line 184 "pars0grm.y" + { yyval = pars_op('=', yyvsp[-2], yyvsp[0]); ;} break; case 43: -#line 180 "pars0grm.y" - { yyval = pars_op(PARS_LE_TOKEN, yyvsp[-2], yyvsp[0]); ;} +#line 185 "pars0grm.y" + { yyval = pars_op('<', yyvsp[-2], yyvsp[0]); ;} break; case 44: -#line 181 "pars0grm.y" - { yyval = pars_op(PARS_NE_TOKEN, yyvsp[-2], yyvsp[0]); ;} +#line 186 "pars0grm.y" + { yyval = pars_op('>', yyvsp[-2], yyvsp[0]); ;} break; case 45: -#line 182 "pars0grm.y" - { yyval = pars_op(PARS_AND_TOKEN, yyvsp[-2], yyvsp[0]); ;} +#line 187 "pars0grm.y" + { yyval = pars_op(PARS_GE_TOKEN, yyvsp[-2], yyvsp[0]); ;} break; case 46: -#line 183 "pars0grm.y" - { yyval = pars_op(PARS_OR_TOKEN, yyvsp[-2], yyvsp[0]); ;} +#line 188 "pars0grm.y" + { yyval = pars_op(PARS_LE_TOKEN, yyvsp[-2], yyvsp[0]); ;} break; case 47: -#line 184 "pars0grm.y" - { yyval = pars_op(PARS_NOT_TOKEN, yyvsp[0], NULL); ;} +#line 189 "pars0grm.y" + { yyval = pars_op(PARS_NE_TOKEN, yyvsp[-2], yyvsp[0]); ;} break; case 48: -#line 186 "pars0grm.y" - { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); ;} +#line 190 "pars0grm.y" + { yyval = pars_op(PARS_AND_TOKEN, yyvsp[-2], yyvsp[0]); ;} break; case 49: -#line 188 "pars0grm.y" - { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); ;} +#line 191 "pars0grm.y" + { yyval = pars_op(PARS_OR_TOKEN, yyvsp[-2], yyvsp[0]); ;} break; case 50: #line 192 "pars0grm.y" - { yyval = &pars_to_char_token; ;} + { yyval = pars_op(PARS_NOT_TOKEN, yyvsp[0], NULL); ;} break; case 51: -#line 193 "pars0grm.y" - { yyval = &pars_to_number_token; ;} +#line 194 "pars0grm.y" + { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); ;} break; case 52: -#line 194 "pars0grm.y" - { yyval = &pars_to_binary_token; ;} +#line 196 "pars0grm.y" + { yyval = pars_op(PARS_NOTFOUND_TOKEN, yyvsp[-2], NULL); ;} break; case 53: -#line 196 "pars0grm.y" - { yyval = &pars_binary_to_number_token; ;} +#line 200 "pars0grm.y" + { yyval = &pars_to_char_token; ;} break; case 54: -#line 197 "pars0grm.y" - { yyval = &pars_substr_token; ;} +#line 201 "pars0grm.y" + { yyval = &pars_to_number_token; ;} break; case 55: -#line 198 "pars0grm.y" - { yyval = &pars_concat_token; ;} +#line 202 "pars0grm.y" + { yyval = &pars_to_binary_token; ;} break; case 56: -#line 199 "pars0grm.y" - { yyval = &pars_instr_token; ;} +#line 204 "pars0grm.y" + { yyval = &pars_binary_to_number_token; ;} break; case 57: -#line 200 "pars0grm.y" - { yyval = &pars_length_token; ;} +#line 205 "pars0grm.y" + { yyval = &pars_substr_token; ;} break; case 58: -#line 201 "pars0grm.y" - { yyval = &pars_sysdate_token; ;} +#line 206 "pars0grm.y" + { yyval = &pars_concat_token; ;} break; case 59: -#line 202 "pars0grm.y" - { yyval = &pars_rnd_token; ;} +#line 207 "pars0grm.y" + { yyval = &pars_instr_token; ;} break; case 60: -#line 203 "pars0grm.y" +#line 208 "pars0grm.y" + { yyval = &pars_length_token; ;} + break; + + case 61: +#line 209 "pars0grm.y" + { yyval = &pars_sysdate_token; ;} + break; + + case 62: +#line 210 "pars0grm.y" + { yyval = &pars_rnd_token; ;} + break; + + case 63: +#line 211 "pars0grm.y" { yyval = &pars_rnd_str_token; ;} break; - case 64: -#line 214 "pars0grm.y" + case 67: +#line 222 "pars0grm.y" { yyval = pars_stored_procedure_call(yyvsp[-4]); ;} break; - case 65: -#line 219 "pars0grm.y" + case 68: +#line 227 "pars0grm.y" { yyval = pars_procedure_call(yyvsp[-3], yyvsp[-1]); ;} break; - case 66: -#line 223 "pars0grm.y" + case 69: +#line 231 "pars0grm.y" { yyval = &pars_replstr_token; ;} break; - case 67: -#line 224 "pars0grm.y" + case 70: +#line 232 "pars0grm.y" { yyval = &pars_printf_token; ;} break; - case 68: -#line 225 "pars0grm.y" + case 71: +#line 233 "pars0grm.y" { yyval = &pars_assert_token; ;} break; - case 69: -#line 229 "pars0grm.y" + case 72: +#line 237 "pars0grm.y" + { yyval = yyvsp[-2]; ;} + break; + + case 73: +#line 241 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 70: -#line 231 "pars0grm.y" + case 74: +#line 243 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 71: -#line 235 "pars0grm.y" + case 75: +#line 247 "pars0grm.y" { yyval = NULL; ;} break; - case 72: -#line 236 "pars0grm.y" + case 76: +#line 248 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 73: -#line 238 "pars0grm.y" + case 77: +#line 250 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 74: -#line 242 "pars0grm.y" + case 78: +#line 254 "pars0grm.y" { yyval = NULL; ;} break; - case 75: -#line 243 "pars0grm.y" + case 79: +#line 255 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]);;} break; - case 76: -#line 244 "pars0grm.y" + case 80: +#line 256 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 77: -#line 248 "pars0grm.y" + case 81: +#line 260 "pars0grm.y" { yyval = yyvsp[0]; ;} break; - case 78: -#line 250 "pars0grm.y" + case 82: +#line 262 "pars0grm.y" { yyval = pars_func(&pars_count_token, que_node_list_add_last(NULL, sym_tab_add_int_lit( pars_sym_tab_global, 1))); ;} break; - case 79: -#line 255 "pars0grm.y" + case 83: +#line 267 "pars0grm.y" { yyval = pars_func(&pars_count_token, que_node_list_add_last(NULL, pars_func(&pars_distinct_token, @@ -1853,410 +1895,436 @@ yyreduce: NULL, yyvsp[-1])))); ;} break; - case 80: -#line 261 "pars0grm.y" + case 84: +#line 273 "pars0grm.y" { yyval = pars_func(&pars_sum_token, que_node_list_add_last(NULL, yyvsp[-1])); ;} break; - case 81: -#line 267 "pars0grm.y" + case 85: +#line 279 "pars0grm.y" { yyval = NULL; ;} break; - case 82: -#line 268 "pars0grm.y" + case 86: +#line 280 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 83: -#line 270 "pars0grm.y" + case 87: +#line 282 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 84: -#line 274 "pars0grm.y" + case 88: +#line 286 "pars0grm.y" { yyval = pars_select_list(&pars_star_denoter, NULL); ;} break; - case 85: -#line 277 "pars0grm.y" + case 89: +#line 289 "pars0grm.y" { yyval = pars_select_list(yyvsp[-2], yyvsp[0]); ;} break; - case 86: -#line 278 "pars0grm.y" + case 90: +#line 290 "pars0grm.y" { yyval = pars_select_list(yyvsp[0], NULL); ;} break; - case 87: -#line 282 "pars0grm.y" + case 91: +#line 294 "pars0grm.y" { yyval = NULL; ;} break; - case 88: -#line 283 "pars0grm.y" + case 92: +#line 295 "pars0grm.y" { yyval = yyvsp[0]; ;} break; - case 89: -#line 287 "pars0grm.y" + case 93: +#line 299 "pars0grm.y" { yyval = NULL; ;} break; - case 90: -#line 289 "pars0grm.y" + case 94: +#line 301 "pars0grm.y" { yyval = &pars_update_token; ;} break; - case 91: -#line 293 "pars0grm.y" + case 95: +#line 305 "pars0grm.y" { yyval = NULL; ;} break; - case 92: -#line 295 "pars0grm.y" + case 96: +#line 307 "pars0grm.y" { yyval = &pars_consistent_token; ;} break; - case 93: -#line 299 "pars0grm.y" + case 97: +#line 311 "pars0grm.y" { yyval = &pars_asc_token; ;} break; - case 94: -#line 300 "pars0grm.y" + case 98: +#line 312 "pars0grm.y" { yyval = &pars_asc_token; ;} break; - case 95: -#line 301 "pars0grm.y" + case 99: +#line 313 "pars0grm.y" { yyval = &pars_desc_token; ;} break; - case 96: -#line 305 "pars0grm.y" + case 100: +#line 317 "pars0grm.y" { yyval = NULL; ;} break; - case 97: -#line 307 "pars0grm.y" + case 101: +#line 319 "pars0grm.y" { yyval = pars_order_by(yyvsp[-1], yyvsp[0]); ;} break; - case 98: -#line 316 "pars0grm.y" + case 102: +#line 328 "pars0grm.y" { yyval = pars_select_statement(yyvsp[-6], yyvsp[-4], yyvsp[-3], yyvsp[-2], yyvsp[-1], yyvsp[0]); ;} break; - case 99: -#line 322 "pars0grm.y" + case 103: +#line 334 "pars0grm.y" { yyval = yyvsp[0]; ;} break; - case 100: -#line 327 "pars0grm.y" + case 104: +#line 339 "pars0grm.y" { yyval = pars_insert_statement(yyvsp[-4], yyvsp[-1], NULL); ;} break; - case 101: -#line 329 "pars0grm.y" + case 105: +#line 341 "pars0grm.y" { yyval = pars_insert_statement(yyvsp[-1], NULL, yyvsp[0]); ;} break; - case 102: -#line 333 "pars0grm.y" + case 106: +#line 345 "pars0grm.y" { yyval = pars_column_assignment(yyvsp[-2], yyvsp[0]); ;} break; - case 103: -#line 337 "pars0grm.y" + case 107: +#line 349 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 104: -#line 339 "pars0grm.y" + case 108: +#line 351 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 105: -#line 345 "pars0grm.y" + case 109: +#line 357 "pars0grm.y" { yyval = yyvsp[0]; ;} break; - case 106: -#line 351 "pars0grm.y" + case 110: +#line 363 "pars0grm.y" { yyval = pars_update_statement_start(FALSE, yyvsp[-2], yyvsp[0]); ;} break; - case 107: -#line 357 "pars0grm.y" + case 111: +#line 369 "pars0grm.y" { yyval = pars_update_statement(yyvsp[-1], NULL, yyvsp[0]); ;} break; - case 108: -#line 362 "pars0grm.y" + case 112: +#line 374 "pars0grm.y" { yyval = pars_update_statement(yyvsp[-1], yyvsp[0], NULL); ;} break; - case 109: -#line 367 "pars0grm.y" + case 113: +#line 379 "pars0grm.y" { yyval = pars_update_statement_start(TRUE, yyvsp[0], NULL); ;} break; - case 110: -#line 373 "pars0grm.y" + case 114: +#line 385 "pars0grm.y" { yyval = pars_update_statement(yyvsp[-1], NULL, yyvsp[0]); ;} break; - case 111: -#line 378 "pars0grm.y" + case 115: +#line 390 "pars0grm.y" { yyval = pars_update_statement(yyvsp[-1], yyvsp[0], NULL); ;} break; - case 112: -#line 383 "pars0grm.y" + case 116: +#line 395 "pars0grm.y" { yyval = pars_row_printf_statement(yyvsp[0]); ;} break; - case 113: -#line 388 "pars0grm.y" + case 117: +#line 400 "pars0grm.y" { yyval = pars_assignment_statement(yyvsp[-2], yyvsp[0]); ;} break; - case 114: -#line 394 "pars0grm.y" + case 118: +#line 406 "pars0grm.y" { yyval = pars_elsif_element(yyvsp[-2], yyvsp[0]); ;} break; - case 115: -#line 398 "pars0grm.y" + case 119: +#line 410 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 116: -#line 400 "pars0grm.y" + case 120: +#line 412 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-1], yyvsp[0]); ;} break; - case 117: -#line 404 "pars0grm.y" + case 121: +#line 416 "pars0grm.y" { yyval = NULL; ;} break; - case 118: -#line 406 "pars0grm.y" + case 122: +#line 418 "pars0grm.y" { yyval = yyvsp[0]; ;} break; - case 119: -#line 407 "pars0grm.y" + case 123: +#line 419 "pars0grm.y" { yyval = yyvsp[0]; ;} break; - case 120: -#line 414 "pars0grm.y" + case 124: +#line 426 "pars0grm.y" { yyval = pars_if_statement(yyvsp[-5], yyvsp[-3], yyvsp[-2]); ;} break; - case 121: -#line 420 "pars0grm.y" + case 125: +#line 432 "pars0grm.y" { yyval = pars_while_statement(yyvsp[-4], yyvsp[-2]); ;} break; - case 122: -#line 428 "pars0grm.y" + case 126: +#line 440 "pars0grm.y" { yyval = pars_for_statement(yyvsp[-8], yyvsp[-6], yyvsp[-4], yyvsp[-2]); ;} break; - case 123: -#line 432 "pars0grm.y" + case 127: +#line 444 "pars0grm.y" + { yyval = pars_exit_statement(); ;} + break; + + case 128: +#line 448 "pars0grm.y" { yyval = pars_return_statement(); ;} break; - case 124: -#line 437 "pars0grm.y" + case 129: +#line 453 "pars0grm.y" { yyval = pars_open_statement( ROW_SEL_OPEN_CURSOR, yyvsp[0]); ;} break; - case 125: -#line 443 "pars0grm.y" + case 130: +#line 459 "pars0grm.y" { yyval = pars_open_statement( ROW_SEL_CLOSE_CURSOR, yyvsp[0]); ;} break; - case 126: -#line 449 "pars0grm.y" - { yyval = pars_fetch_statement(yyvsp[-2], yyvsp[0]); ;} + case 131: +#line 465 "pars0grm.y" + { yyval = pars_fetch_statement(yyvsp[-2], yyvsp[0], NULL); ;} break; - case 127: -#line 454 "pars0grm.y" - { yyval = pars_column_def(yyvsp[-3], yyvsp[-2], yyvsp[-1], yyvsp[0]); ;} + case 132: +#line 467 "pars0grm.y" + { yyval = pars_fetch_statement(yyvsp[-2], NULL, yyvsp[0]); ;} break; - case 128: -#line 458 "pars0grm.y" + case 133: +#line 472 "pars0grm.y" + { yyval = pars_column_def(yyvsp[-4], yyvsp[-3], yyvsp[-2], yyvsp[-1], yyvsp[0]); ;} + break; + + case 134: +#line 476 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 129: -#line 460 "pars0grm.y" + case 135: +#line 478 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 130: -#line 464 "pars0grm.y" + case 136: +#line 482 "pars0grm.y" { yyval = NULL; ;} break; - case 131: -#line 466 "pars0grm.y" + case 137: +#line 484 "pars0grm.y" { yyval = yyvsp[-1]; ;} break; - case 132: -#line 470 "pars0grm.y" + case 138: +#line 488 "pars0grm.y" { yyval = NULL; ;} break; - case 133: -#line 472 "pars0grm.y" + case 139: +#line 490 "pars0grm.y" { yyval = &pars_int_token; /* pass any non-NULL pointer */ ;} break; - case 134: -#line 477 "pars0grm.y" + case 140: +#line 495 "pars0grm.y" { yyval = NULL; ;} break; - case 135: -#line 479 "pars0grm.y" + case 141: +#line 497 "pars0grm.y" { yyval = &pars_int_token; /* pass any non-NULL pointer */ ;} break; - case 136: -#line 486 "pars0grm.y" + case 142: +#line 502 "pars0grm.y" + { yyval = NULL; ;} + break; + + case 143: +#line 504 "pars0grm.y" + { yyval = &pars_int_token; + /* pass any non-NULL pointer */ ;} + break; + + case 144: +#line 511 "pars0grm.y" { yyval = pars_create_table(yyvsp[-4], yyvsp[-2], yyvsp[0]); ;} break; - case 137: -#line 490 "pars0grm.y" + case 145: +#line 515 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 138: -#line 492 "pars0grm.y" + case 146: +#line 517 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 139: -#line 496 "pars0grm.y" + case 147: +#line 521 "pars0grm.y" { yyval = NULL; ;} break; - case 140: -#line 497 "pars0grm.y" + case 148: +#line 522 "pars0grm.y" { yyval = &pars_unique_token; ;} break; - case 141: -#line 501 "pars0grm.y" + case 149: +#line 526 "pars0grm.y" { yyval = NULL; ;} break; - case 142: -#line 502 "pars0grm.y" + case 150: +#line 527 "pars0grm.y" { yyval = &pars_clustered_token; ;} break; - case 143: -#line 510 "pars0grm.y" + case 151: +#line 535 "pars0grm.y" { yyval = pars_create_index(yyvsp[-8], yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]); ;} break; - case 144: -#line 515 "pars0grm.y" + case 152: +#line 540 "pars0grm.y" { yyval = pars_commit_statement(); ;} break; - case 145: -#line 520 "pars0grm.y" + case 153: +#line 545 "pars0grm.y" { yyval = pars_rollback_statement(); ;} break; - case 146: -#line 524 "pars0grm.y" + case 154: +#line 549 "pars0grm.y" { yyval = &pars_int_token; ;} break; - case 147: -#line 525 "pars0grm.y" + case 155: +#line 550 "pars0grm.y" { yyval = &pars_int_token; ;} break; - case 148: -#line 526 "pars0grm.y" + case 156: +#line 551 "pars0grm.y" { yyval = &pars_char_token; ;} break; - case 149: -#line 527 "pars0grm.y" + case 157: +#line 552 "pars0grm.y" { yyval = &pars_binary_token; ;} break; - case 150: -#line 528 "pars0grm.y" + case 158: +#line 553 "pars0grm.y" { yyval = &pars_blob_token; ;} break; - case 151: -#line 533 "pars0grm.y" + case 159: +#line 558 "pars0grm.y" { yyval = pars_parameter_declaration(yyvsp[-2], PARS_INPUT, yyvsp[0]); ;} break; - case 152: -#line 536 "pars0grm.y" + case 160: +#line 561 "pars0grm.y" { yyval = pars_parameter_declaration(yyvsp[-2], PARS_OUTPUT, yyvsp[0]); ;} break; - case 153: -#line 541 "pars0grm.y" + case 161: +#line 566 "pars0grm.y" { yyval = NULL; ;} break; - case 154: -#line 542 "pars0grm.y" + case 162: +#line 567 "pars0grm.y" { yyval = que_node_list_add_last(NULL, yyvsp[0]); ;} break; - case 155: -#line 544 "pars0grm.y" + case 163: +#line 569 "pars0grm.y" { yyval = que_node_list_add_last(yyvsp[-2], yyvsp[0]); ;} break; - case 156: -#line 549 "pars0grm.y" + case 164: +#line 574 "pars0grm.y" { yyval = pars_variable_declaration(yyvsp[-2], yyvsp[-1]); ;} break; - case 160: -#line 561 "pars0grm.y" + case 168: +#line 586 "pars0grm.y" { yyval = pars_cursor_declaration(yyvsp[-3], yyvsp[-1]); ;} break; - case 164: -#line 577 "pars0grm.y" + case 169: +#line 591 "pars0grm.y" + { yyval = pars_function_declaration(yyvsp[-1]); ;} + break; + + case 175: +#line 612 "pars0grm.y" { yyval = pars_procedure_definition(yyvsp[-9], yyvsp[-7], yyvsp[-1]); ;} break; @@ -2265,7 +2333,7 @@ yyreduce: } /* Line 1010 of yacc.c. */ -#line 2269 "pars0grm.tab.c" +#line 2337 "pars0grm.tab.c" yyvsp -= yylen; yyssp -= yylen; @@ -2490,6 +2558,6 @@ yyreturn: } -#line 581 "pars0grm.y" +#line 616 "pars0grm.y" diff --git a/storage/innobase/pars/pars0grm.h b/storage/innobase/pars/pars0grm.h index e35fcf47692..996fc37f13b 100644 --- a/storage/innobase/pars/pars0grm.h +++ b/storage/innobase/pars/pars0grm.h @@ -32,177 +32,187 @@ PARS_INT_LIT = 258, PARS_FLOAT_LIT = 259, PARS_STR_LIT = 260, - PARS_NULL_LIT = 261, - PARS_ID_TOKEN = 262, - PARS_AND_TOKEN = 263, - PARS_OR_TOKEN = 264, - PARS_NOT_TOKEN = 265, - PARS_GE_TOKEN = 266, - PARS_LE_TOKEN = 267, - PARS_NE_TOKEN = 268, - PARS_PROCEDURE_TOKEN = 269, - PARS_IN_TOKEN = 270, - PARS_OUT_TOKEN = 271, - PARS_BINARY_TOKEN = 272, - PARS_BLOB_TOKEN = 273, - PARS_INT_TOKEN = 274, - PARS_INTEGER_TOKEN = 275, - PARS_FLOAT_TOKEN = 276, - PARS_CHAR_TOKEN = 277, - PARS_IS_TOKEN = 278, - PARS_BEGIN_TOKEN = 279, - PARS_END_TOKEN = 280, - PARS_IF_TOKEN = 281, - PARS_THEN_TOKEN = 282, - PARS_ELSE_TOKEN = 283, - PARS_ELSIF_TOKEN = 284, - PARS_LOOP_TOKEN = 285, - PARS_WHILE_TOKEN = 286, - PARS_RETURN_TOKEN = 287, - PARS_SELECT_TOKEN = 288, - PARS_SUM_TOKEN = 289, - PARS_COUNT_TOKEN = 290, - PARS_DISTINCT_TOKEN = 291, - PARS_FROM_TOKEN = 292, - PARS_WHERE_TOKEN = 293, - PARS_FOR_TOKEN = 294, - PARS_DDOT_TOKEN = 295, - PARS_CONSISTENT_TOKEN = 296, - PARS_READ_TOKEN = 297, - PARS_ORDER_TOKEN = 298, - PARS_BY_TOKEN = 299, - PARS_ASC_TOKEN = 300, - PARS_DESC_TOKEN = 301, - PARS_INSERT_TOKEN = 302, - PARS_INTO_TOKEN = 303, - PARS_VALUES_TOKEN = 304, - PARS_UPDATE_TOKEN = 305, - PARS_SET_TOKEN = 306, - PARS_DELETE_TOKEN = 307, - PARS_CURRENT_TOKEN = 308, - PARS_OF_TOKEN = 309, - PARS_CREATE_TOKEN = 310, - PARS_TABLE_TOKEN = 311, - PARS_INDEX_TOKEN = 312, - PARS_UNIQUE_TOKEN = 313, - PARS_CLUSTERED_TOKEN = 314, - PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 315, - PARS_ON_TOKEN = 316, - PARS_ASSIGN_TOKEN = 317, - PARS_DECLARE_TOKEN = 318, - PARS_CURSOR_TOKEN = 319, - PARS_SQL_TOKEN = 320, - PARS_OPEN_TOKEN = 321, - PARS_FETCH_TOKEN = 322, - PARS_CLOSE_TOKEN = 323, - PARS_NOTFOUND_TOKEN = 324, - PARS_TO_CHAR_TOKEN = 325, - PARS_TO_NUMBER_TOKEN = 326, - PARS_TO_BINARY_TOKEN = 327, - PARS_BINARY_TO_NUMBER_TOKEN = 328, - PARS_SUBSTR_TOKEN = 329, - PARS_REPLSTR_TOKEN = 330, - PARS_CONCAT_TOKEN = 331, - PARS_INSTR_TOKEN = 332, - PARS_LENGTH_TOKEN = 333, - PARS_SYSDATE_TOKEN = 334, - PARS_PRINTF_TOKEN = 335, - PARS_ASSERT_TOKEN = 336, - PARS_RND_TOKEN = 337, - PARS_RND_STR_TOKEN = 338, - PARS_ROW_PRINTF_TOKEN = 339, - PARS_COMMIT_TOKEN = 340, - PARS_ROLLBACK_TOKEN = 341, - PARS_WORK_TOKEN = 342, - NEG = 343 + PARS_FIXBINARY_LIT = 261, + PARS_BLOB_LIT = 262, + PARS_NULL_LIT = 263, + PARS_ID_TOKEN = 264, + PARS_AND_TOKEN = 265, + PARS_OR_TOKEN = 266, + PARS_NOT_TOKEN = 267, + PARS_GE_TOKEN = 268, + PARS_LE_TOKEN = 269, + PARS_NE_TOKEN = 270, + PARS_PROCEDURE_TOKEN = 271, + PARS_IN_TOKEN = 272, + PARS_OUT_TOKEN = 273, + PARS_BINARY_TOKEN = 274, + PARS_BLOB_TOKEN = 275, + PARS_INT_TOKEN = 276, + PARS_INTEGER_TOKEN = 277, + PARS_FLOAT_TOKEN = 278, + PARS_CHAR_TOKEN = 279, + PARS_IS_TOKEN = 280, + PARS_BEGIN_TOKEN = 281, + PARS_END_TOKEN = 282, + PARS_IF_TOKEN = 283, + PARS_THEN_TOKEN = 284, + PARS_ELSE_TOKEN = 285, + PARS_ELSIF_TOKEN = 286, + PARS_LOOP_TOKEN = 287, + PARS_WHILE_TOKEN = 288, + PARS_RETURN_TOKEN = 289, + PARS_SELECT_TOKEN = 290, + PARS_SUM_TOKEN = 291, + PARS_COUNT_TOKEN = 292, + PARS_DISTINCT_TOKEN = 293, + PARS_FROM_TOKEN = 294, + PARS_WHERE_TOKEN = 295, + PARS_FOR_TOKEN = 296, + PARS_DDOT_TOKEN = 297, + PARS_CONSISTENT_TOKEN = 298, + PARS_READ_TOKEN = 299, + PARS_ORDER_TOKEN = 300, + PARS_BY_TOKEN = 301, + PARS_ASC_TOKEN = 302, + PARS_DESC_TOKEN = 303, + PARS_INSERT_TOKEN = 304, + PARS_INTO_TOKEN = 305, + PARS_VALUES_TOKEN = 306, + PARS_UPDATE_TOKEN = 307, + PARS_SET_TOKEN = 308, + PARS_DELETE_TOKEN = 309, + PARS_CURRENT_TOKEN = 310, + PARS_OF_TOKEN = 311, + PARS_CREATE_TOKEN = 312, + PARS_TABLE_TOKEN = 313, + PARS_INDEX_TOKEN = 314, + PARS_UNIQUE_TOKEN = 315, + PARS_CLUSTERED_TOKEN = 316, + PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 317, + PARS_ON_TOKEN = 318, + PARS_ASSIGN_TOKEN = 319, + PARS_DECLARE_TOKEN = 320, + PARS_CURSOR_TOKEN = 321, + PARS_SQL_TOKEN = 322, + PARS_OPEN_TOKEN = 323, + PARS_FETCH_TOKEN = 324, + PARS_CLOSE_TOKEN = 325, + PARS_NOTFOUND_TOKEN = 326, + PARS_TO_CHAR_TOKEN = 327, + PARS_TO_NUMBER_TOKEN = 328, + PARS_TO_BINARY_TOKEN = 329, + PARS_BINARY_TO_NUMBER_TOKEN = 330, + PARS_SUBSTR_TOKEN = 331, + PARS_REPLSTR_TOKEN = 332, + PARS_CONCAT_TOKEN = 333, + PARS_INSTR_TOKEN = 334, + PARS_LENGTH_TOKEN = 335, + PARS_SYSDATE_TOKEN = 336, + PARS_PRINTF_TOKEN = 337, + PARS_ASSERT_TOKEN = 338, + PARS_RND_TOKEN = 339, + PARS_RND_STR_TOKEN = 340, + PARS_ROW_PRINTF_TOKEN = 341, + PARS_COMMIT_TOKEN = 342, + PARS_ROLLBACK_TOKEN = 343, + PARS_WORK_TOKEN = 344, + PARS_UNSIGNED_TOKEN = 345, + PARS_EXIT_TOKEN = 346, + PARS_FUNCTION_TOKEN = 347, + NEG = 348 }; #endif #define PARS_INT_LIT 258 #define PARS_FLOAT_LIT 259 #define PARS_STR_LIT 260 -#define PARS_NULL_LIT 261 -#define PARS_ID_TOKEN 262 -#define PARS_AND_TOKEN 263 -#define PARS_OR_TOKEN 264 -#define PARS_NOT_TOKEN 265 -#define PARS_GE_TOKEN 266 -#define PARS_LE_TOKEN 267 -#define PARS_NE_TOKEN 268 -#define PARS_PROCEDURE_TOKEN 269 -#define PARS_IN_TOKEN 270 -#define PARS_OUT_TOKEN 271 -#define PARS_BINARY_TOKEN 272 -#define PARS_BLOB_TOKEN 273 -#define PARS_INT_TOKEN 274 -#define PARS_INTEGER_TOKEN 275 -#define PARS_FLOAT_TOKEN 276 -#define PARS_CHAR_TOKEN 277 -#define PARS_IS_TOKEN 278 -#define PARS_BEGIN_TOKEN 279 -#define PARS_END_TOKEN 280 -#define PARS_IF_TOKEN 281 -#define PARS_THEN_TOKEN 282 -#define PARS_ELSE_TOKEN 283 -#define PARS_ELSIF_TOKEN 284 -#define PARS_LOOP_TOKEN 285 -#define PARS_WHILE_TOKEN 286 -#define PARS_RETURN_TOKEN 287 -#define PARS_SELECT_TOKEN 288 -#define PARS_SUM_TOKEN 289 -#define PARS_COUNT_TOKEN 290 -#define PARS_DISTINCT_TOKEN 291 -#define PARS_FROM_TOKEN 292 -#define PARS_WHERE_TOKEN 293 -#define PARS_FOR_TOKEN 294 -#define PARS_DDOT_TOKEN 295 -#define PARS_CONSISTENT_TOKEN 296 -#define PARS_READ_TOKEN 297 -#define PARS_ORDER_TOKEN 298 -#define PARS_BY_TOKEN 299 -#define PARS_ASC_TOKEN 300 -#define PARS_DESC_TOKEN 301 -#define PARS_INSERT_TOKEN 302 -#define PARS_INTO_TOKEN 303 -#define PARS_VALUES_TOKEN 304 -#define PARS_UPDATE_TOKEN 305 -#define PARS_SET_TOKEN 306 -#define PARS_DELETE_TOKEN 307 -#define PARS_CURRENT_TOKEN 308 -#define PARS_OF_TOKEN 309 -#define PARS_CREATE_TOKEN 310 -#define PARS_TABLE_TOKEN 311 -#define PARS_INDEX_TOKEN 312 -#define PARS_UNIQUE_TOKEN 313 -#define PARS_CLUSTERED_TOKEN 314 -#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 315 -#define PARS_ON_TOKEN 316 -#define PARS_ASSIGN_TOKEN 317 -#define PARS_DECLARE_TOKEN 318 -#define PARS_CURSOR_TOKEN 319 -#define PARS_SQL_TOKEN 320 -#define PARS_OPEN_TOKEN 321 -#define PARS_FETCH_TOKEN 322 -#define PARS_CLOSE_TOKEN 323 -#define PARS_NOTFOUND_TOKEN 324 -#define PARS_TO_CHAR_TOKEN 325 -#define PARS_TO_NUMBER_TOKEN 326 -#define PARS_TO_BINARY_TOKEN 327 -#define PARS_BINARY_TO_NUMBER_TOKEN 328 -#define PARS_SUBSTR_TOKEN 329 -#define PARS_REPLSTR_TOKEN 330 -#define PARS_CONCAT_TOKEN 331 -#define PARS_INSTR_TOKEN 332 -#define PARS_LENGTH_TOKEN 333 -#define PARS_SYSDATE_TOKEN 334 -#define PARS_PRINTF_TOKEN 335 -#define PARS_ASSERT_TOKEN 336 -#define PARS_RND_TOKEN 337 -#define PARS_RND_STR_TOKEN 338 -#define PARS_ROW_PRINTF_TOKEN 339 -#define PARS_COMMIT_TOKEN 340 -#define PARS_ROLLBACK_TOKEN 341 -#define PARS_WORK_TOKEN 342 -#define NEG 343 +#define PARS_FIXBINARY_LIT 261 +#define PARS_BLOB_LIT 262 +#define PARS_NULL_LIT 263 +#define PARS_ID_TOKEN 264 +#define PARS_AND_TOKEN 265 +#define PARS_OR_TOKEN 266 +#define PARS_NOT_TOKEN 267 +#define PARS_GE_TOKEN 268 +#define PARS_LE_TOKEN 269 +#define PARS_NE_TOKEN 270 +#define PARS_PROCEDURE_TOKEN 271 +#define PARS_IN_TOKEN 272 +#define PARS_OUT_TOKEN 273 +#define PARS_BINARY_TOKEN 274 +#define PARS_BLOB_TOKEN 275 +#define PARS_INT_TOKEN 276 +#define PARS_INTEGER_TOKEN 277 +#define PARS_FLOAT_TOKEN 278 +#define PARS_CHAR_TOKEN 279 +#define PARS_IS_TOKEN 280 +#define PARS_BEGIN_TOKEN 281 +#define PARS_END_TOKEN 282 +#define PARS_IF_TOKEN 283 +#define PARS_THEN_TOKEN 284 +#define PARS_ELSE_TOKEN 285 +#define PARS_ELSIF_TOKEN 286 +#define PARS_LOOP_TOKEN 287 +#define PARS_WHILE_TOKEN 288 +#define PARS_RETURN_TOKEN 289 +#define PARS_SELECT_TOKEN 290 +#define PARS_SUM_TOKEN 291 +#define PARS_COUNT_TOKEN 292 +#define PARS_DISTINCT_TOKEN 293 +#define PARS_FROM_TOKEN 294 +#define PARS_WHERE_TOKEN 295 +#define PARS_FOR_TOKEN 296 +#define PARS_DDOT_TOKEN 297 +#define PARS_CONSISTENT_TOKEN 298 +#define PARS_READ_TOKEN 299 +#define PARS_ORDER_TOKEN 300 +#define PARS_BY_TOKEN 301 +#define PARS_ASC_TOKEN 302 +#define PARS_DESC_TOKEN 303 +#define PARS_INSERT_TOKEN 304 +#define PARS_INTO_TOKEN 305 +#define PARS_VALUES_TOKEN 306 +#define PARS_UPDATE_TOKEN 307 +#define PARS_SET_TOKEN 308 +#define PARS_DELETE_TOKEN 309 +#define PARS_CURRENT_TOKEN 310 +#define PARS_OF_TOKEN 311 +#define PARS_CREATE_TOKEN 312 +#define PARS_TABLE_TOKEN 313 +#define PARS_INDEX_TOKEN 314 +#define PARS_UNIQUE_TOKEN 315 +#define PARS_CLUSTERED_TOKEN 316 +#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 317 +#define PARS_ON_TOKEN 318 +#define PARS_ASSIGN_TOKEN 319 +#define PARS_DECLARE_TOKEN 320 +#define PARS_CURSOR_TOKEN 321 +#define PARS_SQL_TOKEN 322 +#define PARS_OPEN_TOKEN 323 +#define PARS_FETCH_TOKEN 324 +#define PARS_CLOSE_TOKEN 325 +#define PARS_NOTFOUND_TOKEN 326 +#define PARS_TO_CHAR_TOKEN 327 +#define PARS_TO_NUMBER_TOKEN 328 +#define PARS_TO_BINARY_TOKEN 329 +#define PARS_BINARY_TO_NUMBER_TOKEN 330 +#define PARS_SUBSTR_TOKEN 331 +#define PARS_REPLSTR_TOKEN 332 +#define PARS_CONCAT_TOKEN 333 +#define PARS_INSTR_TOKEN 334 +#define PARS_LENGTH_TOKEN 335 +#define PARS_SYSDATE_TOKEN 336 +#define PARS_PRINTF_TOKEN 337 +#define PARS_ASSERT_TOKEN 338 +#define PARS_RND_TOKEN 339 +#define PARS_RND_STR_TOKEN 340 +#define PARS_ROW_PRINTF_TOKEN 341 +#define PARS_COMMIT_TOKEN 342 +#define PARS_ROLLBACK_TOKEN 343 +#define PARS_WORK_TOKEN 344 +#define PARS_UNSIGNED_TOKEN 345 +#define PARS_EXIT_TOKEN 346 +#define PARS_FUNCTION_TOKEN 347 +#define NEG 348 diff --git a/storage/innobase/pars/pars0grm.y b/storage/innobase/pars/pars0grm.y index 435025d7386..7f13312fc6e 100644 --- a/storage/innobase/pars/pars0grm.y +++ b/storage/innobase/pars/pars0grm.y @@ -29,10 +29,12 @@ que_node_t */ int yylex(void); %} - + %token PARS_INT_LIT %token PARS_FLOAT_LIT %token PARS_STR_LIT +%token PARS_FIXBINARY_LIT +%token PARS_BLOB_LIT %token PARS_NULL_LIT %token PARS_ID_TOKEN %token PARS_AND_TOKEN @@ -115,6 +117,9 @@ yylex(void); %token PARS_COMMIT_TOKEN %token PARS_ROLLBACK_TOKEN %token PARS_WORK_TOKEN +%token PARS_UNSIGNED_TOKEN +%token PARS_EXIT_TOKEN +%token PARS_FUNCTION_TOKEN %left PARS_AND_TOKEN PARS_OR_TOKEN %left PARS_NOT_TOKEN @@ -133,6 +138,7 @@ statement: | predefined_procedure_call ';' | while_statement ';' | for_statement ';' + | exit_statement ';' | if_statement ';' | return_statement ';' | assignment_statement ';' @@ -165,6 +171,8 @@ exp: | PARS_INT_LIT { $$ = $1;} | PARS_FLOAT_LIT { $$ = $1;} | PARS_STR_LIT { $$ = $1;} + | PARS_FIXBINARY_LIT { $$ = $1;} + | PARS_BLOB_LIT { $$ = $1;} | PARS_NULL_LIT { $$ = $1;} | PARS_SQL_TOKEN { $$ = $1;} | exp '+' exp { $$ = pars_op('+', $1, $3); } @@ -225,6 +233,10 @@ predefined_procedure_name: | PARS_ASSERT_TOKEN { $$ = &pars_assert_token; } ; +user_function_call: + PARS_ID_TOKEN '(' ')' { $$ = $1; } +; + table_list: PARS_ID_TOKEN { $$ = que_node_list_add_last(NULL, $1); } | table_list ',' PARS_ID_TOKEN @@ -262,14 +274,14 @@ select_item: que_node_list_add_last(NULL, $3)); } ; - + select_item_list: /* Nothing */ { $$ = NULL; } | select_item { $$ = que_node_list_add_last(NULL, $1); } | select_item_list ',' select_item { $$ = que_node_list_add_last($1, $3); } ; - + select_list: '*' { $$ = pars_select_list(&pars_star_denoter, NULL); } @@ -377,7 +389,7 @@ delete_statement_positioned: delete_statement_start cursor_positioned { $$ = pars_update_statement($1, $2, NULL); } ; - + row_printf_statement: PARS_ROW_PRINTF_TOKEN select_statement { $$ = pars_row_printf_statement($2); } @@ -428,6 +440,10 @@ for_statement: { $$ = pars_for_statement($2, $4, $6, $8); } ; +exit_statement: + PARS_EXIT_TOKEN { $$ = pars_exit_statement(); } +; + return_statement: PARS_RETURN_TOKEN { $$ = pars_return_statement(); } ; @@ -446,12 +462,14 @@ close_cursor_statement: fetch_statement: PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN variable_list - { $$ = pars_fetch_statement($2, $4); } + { $$ = pars_fetch_statement($2, $4, NULL); } + | PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN user_function_call + { $$ = pars_fetch_statement($2, NULL, $4); } ; column_def: - PARS_ID_TOKEN type_name opt_column_len opt_not_null - { $$ = pars_column_def($1, $2, $3, $4); } + PARS_ID_TOKEN type_name opt_column_len opt_unsigned opt_not_null + { $$ = pars_column_def($1, $2, $3, $4, $5); } ; column_def_list: @@ -466,6 +484,13 @@ opt_column_len: { $$ = $2; } ; +opt_unsigned: + /* Nothing */ { $$ = NULL; } + | PARS_UNSIGNED_TOKEN + { $$ = &pars_int_token; + /* pass any non-NULL pointer */ } +; + opt_not_null: /* Nothing */ { $$ = NULL; } | PARS_NOT_TOKEN PARS_NULL_LIT @@ -479,7 +504,7 @@ not_fit_in_memory: { $$ = &pars_int_token; /* pass any non-NULL pointer */ } ; - + create_table: PARS_CREATE_TOKEN PARS_TABLE_TOKEN PARS_ID_TOKEN '(' column_def_list ')' @@ -550,8 +575,8 @@ variable_declaration: ; variable_declaration_list: - /* Nothing */ - | variable_declaration + /* Nothing */ + | variable_declaration | variable_declaration_list variable_declaration ; @@ -561,10 +586,20 @@ cursor_declaration: { $$ = pars_cursor_declaration($3, $5); } ; +function_declaration: + PARS_DECLARE_TOKEN PARS_FUNCTION_TOKEN PARS_ID_TOKEN ';' + { $$ = pars_function_declaration($3); } +; + +declaration: + cursor_declaration + | function_declaration +; + declaration_list: /* Nothing */ - | cursor_declaration - | declaration_list cursor_declaration + | declaration + | declaration_list declaration ; procedure_definition: @@ -577,5 +612,5 @@ procedure_definition: PARS_END_TOKEN { $$ = pars_procedure_definition($2, $4, $10); } ; - + %% diff --git a/storage/innobase/pars/pars0lex.l b/storage/innobase/pars/pars0lex.l index 4224536d49e..ab1fe446924 100644 --- a/storage/innobase/pars/pars0lex.l +++ b/storage/innobase/pars/pars0lex.l @@ -12,27 +12,11 @@ not automatically generate them from pars0grm.y and pars0lex.l. How to make the InnoDB parser and lexer C files: -1. First do - bison -d pars0grm.y - That generates pars0grm.tab.c and pars0grm.tab.h. +1. Run ./make_flex.sh to generate lexer files. -2. Rename pars0grm.tab.c to pars0grm.c and pars0grm.tab.h to pars0grm.h. +2. Run ./make_bison.sh to generate parser files. -3. Copy pars0grm.h also to /innobase/include - -4. Do - flex pars0lex.l - That generates lex.yy.c. - -5. Rename lex.yy.c to lexyy.c. - -6. Add '#include "univ.i"' before #include <stdio.h> in lexyy.c - (Needed for AIX) - -7. Add a type cast to int to the assignment below the comment - 'need more input.' (Removes a warning on Win64) - -These instructions seem to work at least with bison-1.28 and flex-2.5.4 on +These instructions seem to work at least with bison-1.875d and flex-2.5.31 on Linux. *******************************************************/ @@ -96,11 +80,14 @@ string_append( } %} - + DIGIT [0-9] ID [a-z_A-Z][a-z_A-Z0-9]* +BOUND_LIT \:[a-z_A-Z0-9]+ + %x comment %x quoted +%x id %% {DIGIT}+ { @@ -115,6 +102,15 @@ ID [a-z_A-Z][a-z_A-Z0-9]* return(PARS_FLOAT_LIT); } +{BOUND_LIT} { + ulint type; + + yylval = sym_tab_add_bound_lit(pars_sym_tab_global, + yytext + 1, &type); + + return(type); +} + "'" { /* Quoted character string literals are handled in an explicit start state 'quoted'. This state is entered and the buffer for @@ -153,6 +149,45 @@ In the state 'quoted', only two actions are possible (defined below). */ } } +\" { +/* Quoted identifiers are handled in an explicit start state 'id'. +This state is entered and the buffer for the scanned string is emptied +upon encountering a starting quote. + +In the state 'id', only two actions are possible (defined below). */ + BEGIN(id); + stringbuf_len = 0; +} +<id>[^\"]+ { + /* Got a sequence of characters other than '"': + append to string buffer */ + string_append(yytext, yyleng); +} +<id>\"+ { + /* Got a sequence of '"' characters: + append half of them to string buffer, + as '""' represents a single '"'. + We apply truncating division, + so that '"""' will result in '"'. */ + + string_append(yytext, yyleng / 2); + + /* If we got an odd number of quotes, then the + last quote we got is the terminating quote. + At the end of the string, we return to the + initial start state and report the scanned + identifier. */ + + if (yyleng % 2) { + BEGIN(INITIAL); + yylval = sym_tab_add_id( + pars_sym_tab_global, + (byte*) stringbuf, stringbuf_len); + + return(PARS_ID_TOKEN); + } +} + "NULL" { yylval = sym_tab_add_null_lit(pars_sym_tab_global); @@ -462,6 +497,18 @@ In the state 'quoted', only two actions are possible (defined below). */ return(PARS_WORK_TOKEN); } +"UNSIGNED" { + return(PARS_UNSIGNED_TOKEN); +} + +"EXIT" { + return(PARS_EXIT_TOKEN); +} + +"FUNCTION" { + return(PARS_FUNCTION_TOKEN); +} + {ID} { yylval = sym_tab_add_id(pars_sym_tab_global, (byte*)yytext, diff --git a/storage/innobase/pars/pars0opt.c b/storage/innobase/pars/pars0opt.c index bb41b5da074..4037f50cb5c 100644 --- a/storage/innobase/pars/pars0opt.c +++ b/storage/innobase/pars/pars0opt.c @@ -313,7 +313,6 @@ opt_calc_index_goodness( ulint goodness; ulint n_fields; ulint col_no; - ulint mix_id_col_no; ulint op; ulint j; @@ -326,8 +325,6 @@ opt_calc_index_goodness( n_fields = dict_index_get_n_unique_in_tree(index); - mix_id_col_no = dict_table_get_sys_col_no(index->table, DATA_MIX_ID); - for (j = 0; j < n_fields; j++) { col_no = dict_index_get_nth_col_no(index, j); @@ -335,13 +332,7 @@ opt_calc_index_goodness( exp = opt_look_for_col_in_cond_before(OPT_EQUAL, col_no, sel_node->search_cond, sel_node, nth_table, &op); - if (col_no == mix_id_col_no) { - ut_ad(exp == NULL); - - index_plan[j] = NULL; - *last_op = '='; - goodness += 4; - } else if (exp) { + if (exp) { /* The value for this column is exactly known already at this stage of the join */ @@ -531,7 +522,6 @@ opt_search_plan_for_table( warning */ ulint best_goodness; ulint best_last_op = 0; /* remove warning */ - ulint mix_id_pos; que_node_t* index_plan[256]; que_node_t* best_index_plan[256]; @@ -601,26 +591,6 @@ opt_search_plan_for_table( plan->unique_search = FALSE; } - if ((table->type != DICT_TABLE_ORDINARY) - && (best_index->type & DICT_CLUSTERED)) { - - plan->mixed_index = TRUE; - - mix_id_pos = table->mix_len; - - if (mix_id_pos < n_fields) { - /* We have to add the mix id as a (string) literal - expression to the tuple_exps */ - - plan->tuple_exps[mix_id_pos] = - sym_tab_add_str_lit(pars_sym_tab_global, - table->mix_id_buf, - table->mix_id_len); - } - } else { - plan->mixed_index = FALSE; - } - plan->old_vers_heap = NULL; btr_pcur_init(&(plan->pcur)); @@ -1055,7 +1025,6 @@ opt_clust_access( dict_table_t* table; dict_index_t* clust_index; dict_index_t* index; - dfield_t* dfield; mem_heap_t* heap; ulint n_fields; ulint pos; @@ -1109,22 +1078,7 @@ opt_clust_access( *(plan->clust_map + i) = pos; - ut_ad((pos != ULINT_UNDEFINED) - || ((table->type == DICT_TABLE_CLUSTER_MEMBER) - && (i == table->mix_len))); - } - - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - - /* Preset the mix id field to the mix id constant */ - - dfield = dtuple_get_nth_field(plan->clust_ref, table->mix_len); - - dfield_set_data(dfield, mem_heap_alloc(heap, - table->mix_id_len), - table->mix_id_len); - ut_memcpy(dfield_get_data(dfield), table->mix_id_buf, - table->mix_id_len); + ut_ad(pos != ULINT_UNDEFINED); } } diff --git a/storage/innobase/pars/pars0pars.c b/storage/innobase/pars/pars0pars.c index 1b7a3a653a9..7ef2f65c724 100644 --- a/storage/innobase/pars/pars0pars.c +++ b/storage/innobase/pars/pars0pars.c @@ -373,14 +373,15 @@ pars_resolve_exp_variables_and_types( } /* Not resolved yet: look in the symbol table for a variable - or a cursor with the same name */ + or a cursor or a function with the same name */ node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list); while (node) { if (node->resolved && ((node->token_type == SYM_VAR) - || (node->token_type == SYM_CURSOR)) + || (node->token_type == SYM_CURSOR) + || (node->token_type == SYM_FUNCTION)) && node->name && (sym_node->name_len == node->name_len) && (ut_memcmp(sym_node->name, node->name, @@ -486,7 +487,7 @@ pars_resolve_exp_columns( while (t_node) { table = t_node->table; - n_cols = dict_table_get_n_user_cols(table); + n_cols = dict_table_get_n_cols(table); for (i = 0; i < n_cols; i++) { col = dict_table_get_nth_col(table, i); @@ -787,6 +788,26 @@ pars_cursor_declaration( } /************************************************************************* +Parses a function declaration. */ + +que_node_t* +pars_function_declaration( +/*======================*/ + /* out: sym_node */ + sym_node_t* sym_node) /* in: function id node in the symbol + table */ +{ + sym_node->resolved = TRUE; + sym_node->token_type = SYM_FUNCTION; + + /* Check that the function exists. */ + ut_a(pars_info_get_user_func(pars_sym_tab_global->info, + sym_node->name)); + + return(sym_node); +} + +/************************************************************************* Parses a delete or update statement start. */ upd_node_t* @@ -1085,6 +1106,8 @@ pars_set_dfield_type( pars_res_word_t* type, /* in: pointer to a type token */ ulint len, /* in: length, or 0 */ + ibool is_unsigned, /* in: if TRUE, column is + UNSIGNED. */ ibool is_not_null) /* in: if TRUE, column is NOT NULL. */ { @@ -1094,48 +1117,30 @@ pars_set_dfield_type( flags |= DATA_NOT_NULL; } + if (is_unsigned) { + flags |= DATA_UNSIGNED; + } + if (type == &pars_int_token) { - if (len != 0) { - ut_error; - } + ut_a(len == 0); dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4, 0); } else if (type == &pars_char_token) { - if (len != 0) { - ut_error; - } + ut_a(len == 0); dtype_set(dfield_get_type(dfield), DATA_VARCHAR, DATA_ENGLISH | flags, 0, 0); } else if (type == &pars_binary_token) { - if (len == 0) { - ut_error; - } + ut_a(len != 0); dtype_set(dfield_get_type(dfield), DATA_FIXBINARY, DATA_BINARY_TYPE | flags, len, 0); } else if (type == &pars_blob_token) { - if (len != 0) { - ut_error; - } + ut_a(len == 0); dtype_set(dfield_get_type(dfield), DATA_BLOB, DATA_BINARY_TYPE | flags, 0, 0); - } else if (type == &pars_binary_token) { - if (len == 0) { - ut_error; - } - - dtype_set(dfield_get_type(dfield), DATA_FIXBINARY, - DATA_BINARY_TYPE, len, 0); - } else if (type == &pars_blob_token) { - if (len != 0) { - ut_error; - } - - dtype_set(dfield_get_type(dfield), DATA_BLOB, - DATA_BINARY_TYPE, 0, 0); } else { ut_error; } @@ -1158,7 +1163,7 @@ pars_variable_declaration( node->param_type = PARS_NOT_PARAM; - pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE); + pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE); return(node); } @@ -1347,6 +1352,22 @@ pars_for_statement( } /************************************************************************* +Parses an exit statement. */ + +exit_node_t* +pars_exit_statement(void) +/*=====================*/ + /* out: exit statement node */ +{ + exit_node_t* node; + + node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t)); + node->common.type = QUE_NODE_EXIT; + + return(node); +} + +/************************************************************************* Parses a return-statement. */ return_node_t* @@ -1411,26 +1432,42 @@ pars_procedure_call( } /************************************************************************* -Parses a fetch statement. */ +Parses a fetch statement. into_list or user_func (but not both) must be +non-NULL. */ fetch_node_t* pars_fetch_statement( /*=================*/ /* out: fetch statement node */ sym_node_t* cursor, /* in: cursor node */ - sym_node_t* into_list) /* in: variables to set */ + sym_node_t* into_list, /* in: variables to set, or NULL */ + sym_node_t* user_func) /* in: user function name, or NULL */ { sym_node_t* cursor_decl; fetch_node_t* node; + /* Logical XOR. */ + ut_a(!into_list != !user_func); + node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t)); node->common.type = QUE_NODE_FETCH; pars_resolve_exp_variables_and_types(NULL, cursor); - pars_resolve_exp_list_variables_and_types(NULL, into_list); - node->into_list = into_list; + if (into_list) { + pars_resolve_exp_list_variables_and_types(NULL, into_list); + node->into_list = into_list; + node->func = NULL; + } else { + pars_resolve_exp_variables_and_types(NULL, user_func); + + node->func = pars_info_get_user_func(pars_sym_tab_global->info, + user_func->name); + ut_a(node->func); + + node->into_list = NULL; + } cursor_decl = cursor->alias; @@ -1438,8 +1475,11 @@ pars_fetch_statement( node->cursor_def = cursor_decl->cursor_def; - ut_a(que_node_list_get_len(into_list) - == que_node_list_get_len(node->cursor_def->select_list)); + if (into_list) { + ut_a(que_node_list_get_len(into_list) + == que_node_list_get_len( + node->cursor_def->select_list)); + } return(node); } @@ -1529,6 +1569,8 @@ pars_column_def( pars_res_word_t* type, /* in: data type */ sym_node_t* len, /* in: length of column, or NULL */ + void* is_unsigned, /* in: if not NULL, column + is of type UNSIGNED. */ void* is_not_null) /* in: if not NULL, column is of type NOT NULL. */ { @@ -1541,7 +1583,7 @@ pars_column_def( } pars_set_dfield_type(que_node_get_val(sym_node), type, len2, - is_not_null != NULL); + is_unsigned != NULL, is_not_null != NULL); return(sym_node); } @@ -1798,6 +1840,7 @@ que_t* pars_sql( /*=====*/ /* out, own: the query graph */ + pars_info_t* info, /* in: extra information, or NULL */ const char* str) /* in: SQL string */ { sym_node_t* sym_node; @@ -1817,6 +1860,7 @@ pars_sql( pars_sym_tab_global->sql_string = mem_heap_strdup(heap, str); pars_sym_tab_global->string_len = strlen(str); pars_sym_tab_global->next_char_pos = 0; + pars_sym_tab_global->info = info; yyparse(); @@ -1831,6 +1875,7 @@ pars_sql( graph = pars_sym_tab_global->query_graph; graph->sym_tab = pars_sym_tab_global; + graph->info = info; /* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */ @@ -1867,3 +1912,222 @@ pars_complete_graph_for_exec( return(thr); } + +/******************************************************************** +Create parser info struct.*/ + +pars_info_t* +pars_info_create(void) +/*==================*/ + /* out, own: info struct */ +{ + pars_info_t* info; + mem_heap_t* heap; + + heap = mem_heap_create(512); + + info = mem_heap_alloc(heap, sizeof(*info)); + + info->heap = heap; + info->funcs = NULL; + info->bound_lits = NULL; + info->graph_owns_us = TRUE; + + return(info); +} + +/******************************************************************** +Free info struct and everything it contains.*/ + +void +pars_info_free( +/*===========*/ + pars_info_t* info) /* in: info struct */ +{ + mem_heap_free(info->heap); +} + +/******************************************************************** +Add bound literal. */ + +void +pars_info_add_literal( +/*==================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + const void* address, /* in: address */ + ulint length, /* in: length of data */ + ulint type, /* in: type, e.g. DATA_FIXBINARY */ + ulint prtype) /* in: precise type, e.g. + DATA_UNSIGNED */ +{ + pars_bound_lit_t* pbl; + + ut_ad(!pars_info_get_bound_lit(info, name)); + + pbl = mem_heap_alloc(info->heap, sizeof(*pbl)); + + pbl->name = name; + pbl->address = address; + pbl->length = length; + pbl->type = type; + pbl->prtype = prtype; + + if (!info->bound_lits) { + info->bound_lits = ib_vector_create(info->heap, 8); + } + + ib_vector_push(info->bound_lits, pbl); +} + +/******************************************************************** +Equivalent to pars_info_add_literal(info, name, str, strlen(str), +DATA_VARCHAR, DATA_ENGLISH). */ + +void +pars_info_add_str_literal( +/*======================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + const char* str) /* in: string */ +{ + pars_info_add_literal(info, name, str, strlen(str), + DATA_VARCHAR, DATA_ENGLISH); +} + +/******************************************************************** +Equivalent to: + +char buf[4]; +mach_write_to_4(buf, val); +pars_info_add_literal(info, name, buf, 4, DATA_INT, 0); + +except that the buffer is dynamically allocated from the info struct's +heap. */ + +void +pars_info_add_int4_literal( +/*=======================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + lint val) /* in: value */ +{ + byte* buf = mem_heap_alloc(info->heap, 4); + + mach_write_to_4(buf, val); + pars_info_add_literal(info, name, buf, 4, DATA_INT, 0); +} + +/******************************************************************** +Equivalent to: + +char buf[8]; +mach_write_to_8(buf, val); +pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0); + +except that the buffer is dynamically allocated from the info struct's +heap. */ + +void +pars_info_add_dulint_literal( +/*=========================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + dulint val) /* in: value */ +{ + byte* buf = mem_heap_alloc(info->heap, 8); + + mach_write_to_8(buf, val); + + pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0); +} + +/******************************************************************** +Add user function. */ + +void +pars_info_add_function( +/*===================*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: function name */ + pars_user_func_cb_t func, /* in: function address */ + void* arg) /* in: user-supplied argument */ +{ + pars_user_func_t* puf; + + ut_ad(!pars_info_get_user_func(info, name)); + + puf = mem_heap_alloc(info->heap, sizeof(*puf)); + + puf->name = name; + puf->func = func; + puf->arg = arg; + + if (!info->funcs) { + info->funcs = ib_vector_create(info->heap, 8); + } + + ib_vector_push(info->funcs, puf); +} + +/******************************************************************** +Get user function with the given name.*/ + +pars_user_func_t* +pars_info_get_user_func( +/*====================*/ + /* out: user func, or NULL if not + found */ + pars_info_t* info, /* in: info struct */ + const char* name) /* in: function name to find*/ +{ + ulint i; + ib_vector_t* vec; + + if (!info || !info->funcs) { + return(NULL); + } + + vec = info->funcs; + + for (i = 0; i < ib_vector_size(vec); i++) { + pars_user_func_t* puf = ib_vector_get(vec, i); + + if (strcmp(puf->name, name) == 0) { + return(puf); + } + } + + return(NULL); +} + +/******************************************************************** +Get bound literal with the given name.*/ + +pars_bound_lit_t* +pars_info_get_bound_lit( +/*====================*/ + /* out: bound literal, or NULL if + not found */ + pars_info_t* info, /* in: info struct */ + const char* name) /* in: bound literal name to find */ +{ + ulint i; + ib_vector_t* vec; + + if (!info || !info->bound_lits) { + return(NULL); + } + + vec = info->bound_lits; + + for (i = 0; i < ib_vector_size(vec); i++) { + pars_bound_lit_t* pbl = ib_vector_get(vec, i); + + if (strcmp(pbl->name, name) == 0) { + return(pbl); + } + } + + return(NULL); +} diff --git a/storage/innobase/pars/pars0sym.c b/storage/innobase/pars/pars0sym.c index d8025998f9a..79a1e555b06 100644 --- a/storage/innobase/pars/pars0sym.c +++ b/storage/innobase/pars/pars0sym.c @@ -15,6 +15,7 @@ Created 12/15/1997 Heikki Tuuri #include "mem0mem.h" #include "data0type.h" #include "data0data.h" +#include "pars0grm.h" #include "pars0pars.h" #include "que0que.h" #include "eval0eval.h" @@ -166,6 +167,74 @@ sym_tab_add_str_lit( } /********************************************************************** +Add a bound literal to a symbol table. */ + +sym_node_t* +sym_tab_add_bound_lit( +/*==================*/ + /* out: symbol table node */ + sym_tab_t* sym_tab, /* in: symbol table */ + const char* name, /* in: name of bound literal */ + ulint* lit_type) /* out: type of literal (PARS_*_LIT) */ +{ + sym_node_t* node; + pars_bound_lit_t* blit; + ulint len = 0; + + blit = pars_info_get_bound_lit(sym_tab->info, name); + ut_a(blit); + + node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)); + + node->common.type = QUE_NODE_SYMBOL; + + node->resolved = TRUE; + node->token_type = SYM_LIT; + + node->indirection = NULL; + + switch (blit->type) { + case DATA_FIXBINARY: + len = blit->length; + *lit_type = PARS_FIXBINARY_LIT; + break; + + case DATA_BLOB: + *lit_type = PARS_BLOB_LIT; + break; + + case DATA_VARCHAR: + *lit_type = PARS_STR_LIT; + break; + + case DATA_INT: + ut_a(blit->length > 0); + ut_a(blit->length <= 8); + + len = blit->length; + *lit_type = PARS_INT_LIT; + break; + + default: + ut_error; + } + + dtype_set(&(node->common.val.type), blit->type, blit->prtype, len, 0); + + dfield_set_data(&(node->common.val), blit->address, blit->length); + + node->common.val_buf_size = 0; + node->prefetch_buf = NULL; + node->cursor_def = NULL; + + UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node); + + node->sym_table = sym_tab; + + return(node); +} + +/********************************************************************** Adds an SQL null literal to a symbol table. */ sym_node_t* @@ -220,7 +289,7 @@ sym_tab_add_id( node->resolved = FALSE; node->indirection = NULL; - node->name = mem_heap_strdupl(sym_tab->heap, (char*) name, len + 1); + node->name = mem_heap_strdupl(sym_tab->heap, (char*) name, len); node->name_len = len; UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node); diff --git a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c index e048b94cdc5..59d90eb7e29 100644 --- a/storage/innobase/que/que0que.c +++ b/storage/innobase/que/que0que.c @@ -25,6 +25,7 @@ Created 5/27/1996 Heikki Tuuri #include "log0log.h" #include "eval0proc.h" #include "eval0eval.h" +#include "pars0types.h" #define QUE_PARALLELIZE_LIMIT (64 * 256 * 256 * 256) #define QUE_ROUND_ROBIN_LIMIT (64 * 256 * 256 * 256) @@ -36,6 +37,50 @@ ibool que_trace_on = FALSE; ibool que_always_false = FALSE; +/* Short introduction to query graphs + ================================== + +A query graph consists of nodes linked to each other in various ways. The +execution starts at que_run_threads() which takes a que_thr_t parameter. +que_thr_t contains two fields that control query graph execution: run_node +and prev_node. run_node is the next node to execute and prev_node is the +last node executed. + +Each node has a pointer to a 'next' statement, i.e., its brother, and a +pointer to its parent node. The next pointer is NULL in the last statement +of a block. + +Loop nodes contain a link to the first statement of the enclosed statement +list. While the loop runs, que_thr_step() checks if execution to the loop +node came from its parent or from one of the statement nodes in the loop. If +it came from the parent of the loop node it starts executing the first +statement node in the loop. If it came from one of the statement nodes in +the loop, then it checks if the statement node has another statement node +following it, and runs it if so. + +To signify loop ending, the loop statements (see e.g. while_step()) set +que_thr_t->run_node to the loop node's parent node. This is noticed on the +next call of que_thr_step() and execution proceeds to the node pointed to by +the loop node's 'next' pointer. + +For example, the code: + +X := 1; +WHILE X < 5 LOOP + X := X + 1; + X := X + 1; +X := 5 + +will result in the following node hierarchy, with the X-axis indicating +'next' links and the Y-axis indicating parent/child links: + +A - W - A + | + | + A - A + +A = assign_node_t, W = while_node_t. */ + /* How a stored procedure containing COMMIT or ROLLBACK commands is executed? @@ -128,6 +173,7 @@ que_fork_create( UT_LIST_INIT(fork->thrs); fork->sym_tab = NULL; + fork->info = NULL; fork->heap = heap; @@ -583,6 +629,7 @@ que_graph_free_recursive( break; case QUE_NODE_ASSIGNMENT: + case QUE_NODE_EXIT: case QUE_NODE_RETURN: case QUE_NODE_COMMIT: case QUE_NODE_ROLLBACK: @@ -626,6 +673,10 @@ que_graph_free( sym_tab_free_private(graph->sym_tab); } + if (graph->info && graph->info->graph_owns_us) { + pars_info_free(graph->info); + } + que_graph_free_recursive(graph); mem_heap_free(graph->heap); @@ -1040,6 +1091,37 @@ que_thr_stop_for_mysql_no_error( trx->n_active_thrs--; } +/******************************************************************** +Get the first containing loop node (e.g. while_node_t or for_node_t) for the +given node, or NULL if the node is not within a loop. */ + +que_node_t* +que_node_get_containing_loop_node( +/*==============================*/ + /* out: containing loop node, or NULL. */ + que_node_t* node) /* in: node */ +{ + ut_ad(node); + + for (;;) { + ulint type; + + node = que_node_get_parent(node); + + if (!node) { + break; + } + + type = que_node_get_type(node); + + if ((type == QUE_NODE_FOR) || (type == QUE_NODE_WHILE)) { + break; + } + } + + return(node); +} + /************************************************************************** Prints info of an SQL query graph node. */ @@ -1093,6 +1175,8 @@ que_node_print_info( str = "FOR LOOP"; } else if (type == QUE_NODE_RETURN) { str = "RETURN"; + } else if (type == QUE_NODE_EXIT) { + str = "EXIT"; } else { str = "UNKNOWN NODE TYPE"; } @@ -1120,8 +1204,8 @@ que_thr_step( thr->resource++; - type = que_node_get_type(thr->run_node); node = thr->run_node; + type = que_node_get_type(node); old_thr = thr; @@ -1160,6 +1244,8 @@ que_thr_step( proc_step(thr); } else if (type == QUE_NODE_WHILE) { while_step(thr); + } else { + ut_error; } } else if (type == QUE_NODE_ASSIGNMENT) { assign_step(thr); @@ -1192,6 +1278,8 @@ que_thr_step( thr = row_purge_step(thr); } else if (type == QUE_NODE_RETURN) { thr = return_step(thr); + } else if (type == QUE_NODE_EXIT) { + thr = exit_step(thr); } else if (type == QUE_NODE_ROLLBACK) { thr = trx_rollback_step(thr); } else if (type == QUE_NODE_CREATE_TABLE) { @@ -1204,7 +1292,11 @@ que_thr_step( ut_error; } - old_thr->prev_node = node; + if (type == QUE_NODE_EXIT) { + old_thr->prev_node = que_node_get_containing_loop_node(node); + } else { + old_thr->prev_node = node; + } return(thr); } @@ -1274,3 +1366,33 @@ loop: goto loop; } + +/************************************************************************* +Evaluate the given SQL */ + +ulint +que_eval_sql( +/*=========*/ + pars_info_t* info, /* out: error code or DB_SUCCESS */ + const char* sql, /* in: info struct, or NULL */ + trx_t* trx) /* in: trx */ +{ + que_thr_t* thr; + que_t* graph; + + graph = pars_sql(info, sql); + ut_a(graph); + + graph->trx = trx; + trx->graph = NULL; + + graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + + ut_a(thr = que_fork_start_command(graph)); + + que_run_threads(thr); + + que_graph_free(graph); + + return(trx->error_state); +} diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index c80a61cc729..e47d6a621a7 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -28,6 +28,7 @@ Created 4/20/1996 Heikki Tuuri #include "eval0eval.h" #include "data0data.h" #include "usr0sess.h" +#include "buf0lru.h" #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 @@ -139,7 +140,6 @@ row_ins_alloc_sys_fields( mem_heap_t* heap; dict_col_t* col; dfield_t* dfield; - ulint len; byte* ptr; row = node->row; @@ -161,21 +161,6 @@ row_ins_alloc_sys_fields( node->row_id_buf = ptr; - if (table->type == DICT_TABLE_CLUSTER_MEMBER) { - - /* 2. Fill in the dfield for mix id */ - - col = dict_table_get_sys_col(table, DATA_MIX_ID); - - dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - - len = mach_dulint_get_compressed_size(table->mix_id); - ptr = mem_heap_alloc(heap, DATA_MIX_ID_LEN); - - mach_dulint_write_compressed(ptr, table->mix_id); - dfield_set_data(dfield, ptr, len); - } - /* 3. Allocate buffer for trx id */ col = dict_table_get_sys_col(table, DATA_TRX_ID); @@ -279,10 +264,17 @@ row_ins_sec_index_entry_by_modify( } } else { ut_a(mode == BTR_MODIFY_TREE); + if (buf_LRU_buf_pool_running_out()) { + + err = DB_LOCK_TABLE_FULL; + + goto func_exit; + } + err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG, cursor, &dummy_big_rec, update, 0, thr, mtr); } - +func_exit: mem_heap_free(heap); return(err); @@ -344,10 +336,16 @@ row_ins_clust_index_entry_by_modify( } } else { ut_a(mode == BTR_MODIFY_TREE); + if (buf_LRU_buf_pool_running_out()) { + + err = DB_LOCK_TABLE_FULL; + + goto func_exit; + } err = btr_cur_pessimistic_update(0, cursor, big_rec, update, 0, thr, mtr); } - +func_exit: mem_heap_free(heap); return(err); @@ -1882,7 +1880,6 @@ row_ins_duplicate_error_in_clust( err = DB_DUPLICATE_KEY; goto func_exit; } - mem_heap_free(heap); } ut_a(!(cursor->index->type & DICT_CLUSTERED)); @@ -1891,6 +1888,9 @@ row_ins_duplicate_error_in_clust( err = DB_SUCCESS; func_exit: + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } return(err); #else /* UNIV_HOTBACKUP */ /* This function depends on MySQL code that is not included in @@ -2091,6 +2091,12 @@ row_ins_index_entry_low( &insert_rec, &big_rec, thr, &mtr); } else { ut_a(mode == BTR_MODIFY_TREE); + if (buf_LRU_buf_pool_running_out()) { + + err = DB_LOCK_TABLE_FULL; + + goto function_exit; + } err = btr_cur_pessimistic_insert(0, &cursor, entry, &insert_rec, &big_rec, thr, &mtr); } @@ -2429,7 +2435,15 @@ row_ins_step( /* If this is the first time this node is executed (or when execution resumes after wait for the table IX lock), set an - IX lock on the table and reset the possible select node. */ + IX lock on the table and reset the possible select node. MySQL's + partitioned table code may also call an insert within the same + SQL statement AFTER it has used this table handle to do a search. + This happens, for example, when a row update moves it to another + partition. In that case, we have already set the IX lock on the + table during the search operation, and there is no need to set + it again here. But we must write trx->id to node->trx_id_buf. */ + + trx_write_trx_id(node->trx_id_buf, trx->id); if (node->state == INS_NODE_SET_IX_LOCK) { @@ -2437,13 +2451,11 @@ row_ins_step( its transaction, or it has been committed: */ if (UT_DULINT_EQ(trx->id, node->trx_id)) { - /* No need to do IX-locking or write trx id to buf */ + /* No need to do IX-locking */ goto same_trx; } - trx_write_trx_id(node->trx_id_buf, trx->id); - err = lock_table(0, node->table, LOCK_IX, thr); if (err != DB_SUCCESS) { diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 4dbe5128974..56574618f9a 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -85,9 +85,11 @@ row_mysql_is_system_table( system table name */ const char* name) { - if (memcmp(name, "mysql/", 6)) { + if (strncmp(name, "mysql/", 6) != 0) { + return(FALSE); } + return(0 == strcmp(name + 6, "host") || 0 == strcmp(name + 6, "user") || 0 == strcmp(name + 6, "db")); @@ -1435,7 +1437,8 @@ run_again: } /************************************************************************* -This can only be used when srv_locks_unsafe_for_binlog is TRUE. Before +This can only be used when srv_locks_unsafe_for_binlog is TRUE or +this session is using a READ COMMITTED isolation level. Before calling this function we must use trx_reset_new_rec_lock_info() and trx_register_new_rec_lock() to store the information which new record locks really were set. This function removes a newly set lock under prebuilt->pcur, @@ -1466,11 +1469,13 @@ row_unlock_for_mysql( ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - if (!srv_locks_unsafe_for_binlog) { + if (!(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED)) { fprintf(stderr, "InnoDB: Error: calling row_unlock_for_mysql though\n" -"InnoDB: srv_locks_unsafe_for_binlog is FALSE.\n"); +"InnoDB: srv_locks_unsafe_for_binlog is FALSE and\n" +"InnoDB: this session is not using READ COMMITTED isolation level.\n"); return(DB_SUCCESS); } @@ -1670,7 +1675,9 @@ row_mysql_recover_tmp_table( if (!ptr) { /* table name does not begin with "/rsql" */ + dict_mem_table_free(table); trx_commit_for_mysql(trx); + return(DB_ERROR); } else { @@ -1782,6 +1789,7 @@ row_create_table_for_mysql( const char* table_name; ulint table_name_len; ulint err; + ulint i; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG @@ -1799,6 +1807,7 @@ row_create_table_for_mysql( "InnoDB: with raw, and innodb_force_... is removed.\n", stderr); + dict_mem_table_free(table); trx_commit_for_mysql(trx); return(DB_ERROR); @@ -1813,11 +1822,25 @@ row_create_table_for_mysql( "InnoDB: MySQL system tables must be of the MyISAM type!\n", table->name); + dict_mem_table_free(table); trx_commit_for_mysql(trx); return(DB_ERROR); } + /* Check that no reserved column names are used. */ + for (i = 0; i < dict_table_get_n_user_cols(table); i++) { + dict_col_t* col = dict_table_get_nth_col(table, i); + + if (dict_col_name_is_reserved(col->name)) { + + dict_mem_table_free(table); + trx_commit_for_mysql(trx); + + return(DB_ERROR); + } + } + trx_start_if_not_started(trx); if (row_mysql_is_recovered_tmp_table(table->name)) { @@ -2361,11 +2384,9 @@ row_discard_tablespace_for_mysql( dict_foreign_t* foreign; dulint new_id; dict_table_t* table; - que_thr_t* thr; - que_t* graph = NULL; ibool success; ulint err; - char* buf; + pars_info_t* info = NULL; /* How do we prevent crashes caused by ongoing operations on the table? Old operations could try to access non-existent pages. @@ -2387,36 +2408,6 @@ discard ongoing operations. 5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we do not allow the discard. We also reserve the data dictionary latch. */ - static const char discard_tablespace_proc1[] = - "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" - "old_id CHAR;\n" - "new_id CHAR;\n" - "new_id_low INT;\n" - "new_id_high INT;\n" - "table_name CHAR;\n" - "BEGIN\n" - "table_name := '"; - static const char discard_tablespace_proc2[] = - "';\n" - "new_id_high := %lu;\n" - "new_id_low := %lu;\n" - "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" - "SELECT ID INTO old_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = table_name;\n" - "IF (SQL %% NOTFOUND) THEN\n" - " COMMIT WORK;\n" - " RETURN;\n" - "END IF;\n" - "UPDATE SYS_TABLES SET ID = new_id\n" - "WHERE ID = old_id;\n" - "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "COMMIT WORK;\n" - "END;\n"; - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = "discarding tablespace"; @@ -2496,35 +2487,34 @@ do not allow the discard. We also reserve the data dictionary latch. */ new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - buf = mem_alloc((sizeof discard_tablespace_proc1) + - (sizeof discard_tablespace_proc2) + - 20 + ut_strlenq(name, '\'')); - - memcpy(buf, discard_tablespace_proc1, sizeof discard_tablespace_proc1); - sprintf(ut_strcpyq(buf + (sizeof discard_tablespace_proc1 - 1), - '\'', name), - discard_tablespace_proc2, - (ulong) ut_dulint_get_high(new_id), - (ulong) ut_dulint_get_low(new_id)); - - graph = pars_sql(buf); - - ut_a(graph); - /* Remove any locks there are on the table or its records */ - lock_reset_all_on_table(table); - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + info = pars_info_create(); - ut_a(thr = que_fork_start_command(graph)); + pars_info_add_str_literal(info, "table_name", name); + pars_info_add_dulint_literal(info, "new_id", new_id); - que_run_threads(thr); - - err = trx->error_state; + err = que_eval_sql(info, + "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" + "old_id CHAR;\n" + "BEGIN\n" + "SELECT ID INTO old_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = :table_name;\n" + "IF (SQL % NOTFOUND) THEN\n" + " COMMIT WORK;\n" + " RETURN;\n" + "END IF;\n" + "UPDATE SYS_TABLES SET ID = :new_id\n" + " WHERE ID = old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = old_id;\n" + "COMMIT WORK;\n" + "END;\n" + , trx); if (err != DB_SUCCESS) { trx->error_state = DB_SUCCESS; @@ -2548,13 +2538,10 @@ do not allow the discard. We also reserve the data dictionary latch. */ table->ibd_file_missing = TRUE; } } + funct_exit: row_mysql_unlock_data_dictionary(trx); - if (graph) { - que_graph_free(graph); - } - trx_commit_for_mysql(trx); trx->op_info = ""; @@ -2715,9 +2702,7 @@ row_truncate_table_for_mysql( btr_pcur_t pcur; mtr_t mtr; dulint new_id; - char* sql; - que_thr_t* thr; - que_t* graph = NULL; + pars_info_t* info = NULL; /* How do we prevent crashes caused by ongoing operations on the table? Old operations could try to access non-existent pages. @@ -2745,30 +2730,6 @@ by DISCARD TABLESPACE.) 5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we do not allow the TRUNCATE. We also reserve the data dictionary latch. */ - static const char renumber_tablespace_proc[] = - "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" - "old_id CHAR;\n" - "new_id CHAR;\n" - "old_id_low INT;\n" - "old_id_high INT;\n" - "new_id_low INT;\n" - "new_id_high INT;\n" - "BEGIN\n" - "old_id_high := %lu;\n" - "old_id_low := %lu;\n" - "new_id_high := %lu;\n" - "new_id_low := %lu;\n" - "old_id := CONCAT(TO_BINARY(old_id_high, 4), TO_BINARY(old_id_low, 4));\n" - "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" - "UPDATE SYS_TABLES SET ID = new_id\n" - "WHERE ID = old_id;\n" - "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "COMMIT WORK;\n" - "END;\n"; - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(table); @@ -2929,35 +2890,27 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */ btr_pcur_close(&pcur); mtr_commit(&mtr); - new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - - mem_heap_empty(heap); - sql = mem_heap_alloc(heap, (sizeof renumber_tablespace_proc) + 40); - sprintf(sql, renumber_tablespace_proc, - (ulong) ut_dulint_get_high(table->id), - (ulong) ut_dulint_get_low(table->id), - (ulong) ut_dulint_get_high(new_id), - (ulong) ut_dulint_get_low(new_id)); - - graph = pars_sql(sql); - - ut_a(graph); - mem_heap_free(heap); - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - thr = que_fork_start_command(graph); - ut_a(thr); + info = pars_info_create(); - que_run_threads(thr); + pars_info_add_dulint_literal(info, "old_id", table->id); + pars_info_add_dulint_literal(info, "new_id", new_id); - que_graph_free(graph); - - err = trx->error_state; + err = que_eval_sql(info, + "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" + "BEGIN\n" + "UPDATE SYS_TABLES SET ID = :new_id\n" + " WHERE ID = :old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = :old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = :old_id;\n" + "COMMIT WORK;\n" + "END;\n" + , trx); if (err != DB_SUCCESS) { trx->error_state = DB_SUCCESS; @@ -3007,83 +2960,13 @@ row_drop_table_for_mysql( dict_foreign_t* foreign; dict_table_t* table; ulint space_id; - que_thr_t* thr; - que_t* graph; ulint err; const char* table_name; ulint namelen; char* dir_path_of_temp_table = NULL; ibool success; ibool locked_dictionary = FALSE; - char* quoted_name; - char* sql; - - /* We use the private SQL parser of Innobase to generate the - query graphs needed in deleting the dictionary data from system - tables in Innobase. Deleting a row from SYS_INDEXES table also - frees the file segments of the B-tree associated with the index. */ - - static const char str1[] = - "PROCEDURE DROP_TABLE_PROC () IS\n" - "table_name CHAR;\n" - "sys_foreign_id CHAR;\n" - "table_id CHAR;\n" - "index_id CHAR;\n" - "foreign_id CHAR;\n" - "found INT;\n" - "BEGIN\n" - "table_name := "; - static const char str2[] = - ";\n" - "SELECT ID INTO table_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = table_name;\n" - "IF (SQL % NOTFOUND) THEN\n" - " COMMIT WORK;\n" - " RETURN;\n" - "END IF;\n" - "found := 1;\n" - "SELECT ID INTO sys_foreign_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = 'SYS_FOREIGN';\n" - "IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - "END IF;\n" - "IF (table_name = 'SYS_FOREIGN') THEN\n" - " found := 0;\n" - "END IF;\n" - "IF (table_name = 'SYS_FOREIGN_COLS') THEN\n" - " found := 0;\n" - "END IF;\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = table_name\n" - " AND TO_BINARY(FOR_NAME) = TO_BINARY(table_name);\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE" - " DELETE FROM SYS_FOREIGN_COLS WHERE ID = foreign_id;\n" - " DELETE FROM SYS_FOREIGN WHERE ID = foreign_id;\n" - " END IF;\n" - "END LOOP;\n" - "found := 1;\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO index_id\n" - " FROM SYS_INDEXES\n" - " WHERE TABLE_ID = table_id;\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE" - " DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n" - " DELETE FROM SYS_INDEXES WHERE ID = index_id\n" - " AND TABLE_ID = table_id;\n" - " END IF;\n" - "END LOOP;\n" - "DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n" - "DELETE FROM SYS_TABLES WHERE ID = table_id;\n" - "COMMIT WORK;\n" - "END;\n"; + pars_info_t* info = NULL; ut_a(name != NULL); @@ -3138,14 +3021,6 @@ row_drop_table_for_mysql( srv_print_innodb_table_monitor = FALSE; } - quoted_name = mem_strdupq(name, '\''); - namelen = strlen(quoted_name); - sql = mem_alloc((sizeof str1) + (sizeof str2) - 2 + 1 + namelen); - memcpy(sql, str1, (sizeof str1) - 1); - memcpy(sql + (sizeof str1) - 1, quoted_name, namelen); - memcpy(sql + (sizeof str1) - 1 + namelen, str2, sizeof str2); - mem_free(quoted_name); - /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ @@ -3163,16 +3038,6 @@ row_drop_table_for_mysql( ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - graph = pars_sql(sql); - - ut_a(graph); - mem_free(sql); - - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - table = dict_table_get_low(name); if (!table) { @@ -3296,18 +3161,80 @@ fputs(" InnoDB: You are trying to drop table ", stderr); trx->dict_operation = TRUE; trx->table_id = table->id; - ut_a(thr = que_fork_start_command(graph)); + /* We use the private SQL parser of Innobase to generate the + query graphs needed in deleting the dictionary data from system + tables in Innobase. Deleting a row from SYS_INDEXES table also + frees the file segments of the B-tree associated with the index. */ - que_run_threads(thr); + info = pars_info_create(); - err = trx->error_state; + pars_info_add_str_literal(info, "table_name", name); + + err = que_eval_sql(info, + "PROCEDURE DROP_TABLE_PROC () IS\n" + "sys_foreign_id CHAR;\n" + "table_id CHAR;\n" + "index_id CHAR;\n" + "foreign_id CHAR;\n" + "found INT;\n" + "BEGIN\n" + "SELECT ID INTO table_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = :table_name;\n" + "IF (SQL % NOTFOUND) THEN\n" + " COMMIT WORK;\n" + " RETURN;\n" + "END IF;\n" + "found := 1;\n" + "SELECT ID INTO sys_foreign_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = 'SYS_FOREIGN';\n" + "IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + "END IF;\n" + "IF (:table_name = 'SYS_FOREIGN') THEN\n" + " found := 0;\n" + "END IF;\n" + "IF (:table_name = 'SYS_FOREIGN_COLS') THEN\n" + " found := 0;\n" + "END IF;\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = :table_name\n" + " AND TO_BINARY(FOR_NAME) = TO_BINARY(:table_name);\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE" + " DELETE FROM SYS_FOREIGN_COLS WHERE ID = foreign_id;\n" + " DELETE FROM SYS_FOREIGN WHERE ID = foreign_id;\n" + " END IF;\n" + "END LOOP;\n" + "found := 1;\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO index_id\n" + " FROM SYS_INDEXES\n" + " WHERE TABLE_ID = table_id;\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE" + " DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n" + " DELETE FROM SYS_INDEXES WHERE ID = index_id\n" + " AND TABLE_ID = table_id;\n" + " END IF;\n" + "END LOOP;\n" + "DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n" + "DELETE FROM SYS_TABLES WHERE ID = table_id;\n" + "COMMIT WORK;\n" + "END;\n" + , trx); if (err != DB_SUCCESS) { ut_a(err == DB_OUT_OF_FILE_SPACE); err = DB_MUST_GET_MORE_FILE_SPACE; - row_mysql_handle_errors(&err, trx, thr, NULL); + row_mysql_handle_errors(&err, trx, NULL, NULL); ut_error; } else { @@ -3385,8 +3312,6 @@ funct_exit: mem_free(dir_path_of_temp_table); } - que_graph_free(graph); - trx_commit_for_mysql(trx); trx->op_info = ""; @@ -3491,6 +3416,62 @@ row_is_mysql_tmp_table_name( return(strstr(name, "/@0023sql") != NULL); } +/******************************************************************** +Delete a single constraint. */ +static +int +row_delete_constraint_low( +/*======================*/ + /* out: error code or DB_SUCCESS */ + const char* id, /* in: constraint id */ + trx_t* trx) /* in: transaction handle */ +{ + pars_info_t* info = pars_info_create(); + + pars_info_add_str_literal(info, "id", id); + + return(que_eval_sql(info, + "PROCEDURE DELETE_CONSTRAINT () IS\n" + "BEGIN\n" + "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" + "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" + "END;\n" + , trx)); +} + +/******************************************************************** +Delete a single constraint. */ +static +int +row_delete_constraint( +/*==================*/ + /* out: error code or DB_SUCCESS */ + const char* id, /* in: constraint id */ + const char* database_name, /* in: database name, with the + trailing '/' */ + mem_heap_t* heap, /* in: memory heap */ + trx_t* trx) /* in: transaction handle */ +{ + ulint err; + + /* New format constraints have ids <databasename>/<constraintname>. */ + err = row_delete_constraint_low( + mem_heap_strcat(heap, database_name, id), trx); + + if ((err == DB_SUCCESS) && !strchr(id, '/')) { + /* Old format < 4.0.18 constraints have constraint ids + <number>_<number>. We only try deleting them if the + constraint name does not contain a '/' character, otherwise + deleting a new format constraint named 'foo/bar' from + database 'baz' would remove constraint 'bar' from database + 'foo', if it existed. */ + + err = row_delete_constraint_low(id, trx); + } + + return(err); +} + /************************************************************************* Renames a table for MySQL. */ @@ -3503,100 +3484,13 @@ row_rename_table_for_mysql( trx_t* trx) /* in: transaction handle */ { dict_table_t* table; - que_thr_t* thr; - que_t* graph = NULL; ulint err; - /* We use the private SQL parser of Innobase to generate the - query graphs needed in deleting the dictionary data from system - tables in Innobase. Deleting a row from SYS_INDEXES table also - frees the file segments of the B-tree associated with the index. */ - static const char str1[] = - "PROCEDURE RENAME_TABLE_PROC () IS\n" - "new_table_name CHAR;\n" - "old_table_name CHAR;\n" - "gen_constr_prefix CHAR;\n" - "new_db_name CHAR;\n" - "foreign_id CHAR;\n" - "new_foreign_id CHAR;\n" - "old_db_name_len INT;\n" - "old_t_name_len INT;\n" - "new_db_name_len INT;\n" - "id_len INT;\n" - "found INT;\n" - "BEGIN\n" - "new_table_name := '"; - static const char str2[] = - "';\nold_table_name := '"; - static const char str3[] = - "';\n" - "UPDATE SYS_TABLES SET NAME = new_table_name\n" - "WHERE NAME = old_table_name;\n"; - static const char str4a1[] = /* drop some constraints of tmp tables */ - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '"; - static const char str4a2[] = "';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '"; - static const char str4a3[] = "';\n"; - static const char str4b[] = /* rename all constraints */ - "found := 1;\n" - "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" - "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" - "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" - "old_t_name_len := LENGTH(old_table_name);\n" - "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = old_table_name\n" - " AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE\n" - " UPDATE SYS_FOREIGN\n" - " SET FOR_NAME = new_table_name\n" - " WHERE ID = foreign_id;\n" - " id_len := LENGTH(foreign_id);\n" - " IF (INSTR(foreign_id, '/') > 0) THEN\n" - " IF (INSTR(foreign_id,\n" - " gen_constr_prefix) > 0)\n" - " THEN\n" - " new_foreign_id :=\n" - " CONCAT(new_table_name,\n" - " SUBSTR(foreign_id, old_t_name_len,\n" - " id_len - old_t_name_len));\n" - " ELSE\n" - " new_foreign_id :=\n" - " CONCAT(new_db_name,\n" - " SUBSTR(foreign_id,\n" - " old_db_name_len,\n" - " id_len - old_db_name_len));\n" - " END IF;\n" - " UPDATE SYS_FOREIGN\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " UPDATE SYS_FOREIGN_COLS\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " END IF;\n" - " END IF;\n" - "END LOOP;\n" - "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" - "WHERE REF_NAME = old_table_name\n" - " AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);\n"; - static const char str5[] = - "END;\n"; - mem_heap_t* heap = NULL; const char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; ibool recovering_temp_table = FALSE; ibool old_is_tmp, new_is_tmp; - ulint len; - ulint i; - ibool success; - /* length of database name; 0 if not renaming to a temporary table */ - ulint db_name_len; - char* sql; - char* sqlend; + pars_info_t* info = NULL; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(old_name != NULL); @@ -3674,13 +3568,7 @@ row_rename_table_for_mysql( goto funct_exit; } - /* calculate the length of the SQL string */ - len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4 - + ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\''); - if (new_is_tmp) { - db_name_len = dict_get_db_name_len(old_name) + 1; - /* MySQL is doing an ALTER TABLE command and it renames the original table to a temporary table name. We want to preserve the original foreign key constraint definitions despite the @@ -3690,110 +3578,124 @@ row_rename_table_for_mysql( heap = mem_heap_create(100); err = dict_foreign_parse_drop_constraints(heap, trx, - table, - &n_constraints_to_drop, - &constraints_to_drop); + table, &n_constraints_to_drop, &constraints_to_drop); + if (err != DB_SUCCESS) { goto funct_exit; } + } - /* reserve space for all database names */ - len += 2 * n_constraints_to_drop - * (ut_strlenq(old_name, '\'') - - ut_strlenq(old_name + db_name_len, '\'')); + /* We use the private SQL parser of Innobase to generate the query + graphs needed in deleting the dictionary data from system tables in + Innobase. Deleting a row from SYS_INDEXES table also frees the file + segments of the B-tree associated with the index. */ - for (i = 0; i < n_constraints_to_drop; i++) { - ulint addlen - = 2 * ut_strlenq(constraints_to_drop[i], '\'') - + ((sizeof str4a1) + (sizeof str4a2) - + (sizeof str4a3) - 3); - if (!strchr(constraints_to_drop[i], '/')) { - addlen *= 2; - } - len += addlen; - } - } else { - db_name_len = 0; - len += (sizeof str4b) - 1; - } + info = pars_info_create(); - sql = sqlend = mem_alloc(len + 1); - memcpy(sql, str1, (sizeof str1) - 1); - sqlend += (sizeof str1) - 1; - sqlend = ut_strcpyq(sqlend, '\'', new_name); - memcpy(sqlend, str2, (sizeof str2) - 1); - sqlend += (sizeof str2) - 1; - sqlend = ut_strcpyq(sqlend, '\'', old_name); - memcpy(sqlend, str3, (sizeof str3) - 1); - sqlend += (sizeof str3) - 1; - - if (db_name_len) { - /* Internally, old format < 4.0.18 constraints have as the - constraint id <number>_<number>, while new format constraints - have <databasename>/<constraintname>. */ + pars_info_add_str_literal(info, "new_table_name", new_name); + pars_info_add_str_literal(info, "old_table_name", old_name); - for (i = 0; i < n_constraints_to_drop; i++) { - memcpy(sqlend, str4a1, (sizeof str4a1) - 1); - sqlend += (sizeof str4a1) - 1; - sqlend = ut_memcpyq(sqlend, '\'', - old_name, db_name_len); - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a2, (sizeof str4a2) - 1); - sqlend += (sizeof str4a2) - 1; - sqlend = ut_memcpyq(sqlend, '\'', - old_name, db_name_len); - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a3, (sizeof str4a3) - 1); - sqlend += (sizeof str4a3) - 1; - - if (!strchr(constraints_to_drop[i], '/')) { - /* If this happens to be an old format - constraint, let us delete it. Since all new - format constraints contain '/', it does no - harm to run these DELETEs anyway. */ - - memcpy(sqlend, str4a1, (sizeof str4a1) - 1); - sqlend += (sizeof str4a1) - 1; - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a2, (sizeof str4a2) - 1); - sqlend += (sizeof str4a2) - 1; - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a3, (sizeof str4a3) - 1); - sqlend += (sizeof str4a3) - 1; - } - } - } - else { - memcpy(sqlend, str4b, (sizeof str4b) - 1); - sqlend += (sizeof str4b) - 1; - } + err = que_eval_sql(info, + "PROCEDURE RENAME_TABLE () IS\n" + "BEGIN\n" + "UPDATE SYS_TABLES SET NAME = :new_table_name\n" + " WHERE NAME = :old_table_name;\n" + "END;\n" + , trx); - memcpy(sqlend, str5, sizeof str5); - sqlend += sizeof str5; + if (err != DB_SUCCESS) { - ut_a(sqlend == sql + len + 1); + goto end; + } - graph = pars_sql(sql); + if (!new_is_tmp) { + /* Rename all constraints. */ - ut_a(graph); - mem_free(sql); + info = pars_info_create(); - graph->trx = trx; - trx->graph = NULL; + pars_info_add_str_literal(info, "new_table_name", new_name); + pars_info_add_str_literal(info, "old_table_name", old_name); - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + err = que_eval_sql(info, + "PROCEDURE RENAME_CONSTRAINT_IDS () IS\n" + "gen_constr_prefix CHAR;\n" + "new_db_name CHAR;\n" + "foreign_id CHAR;\n" + "new_foreign_id CHAR;\n" + "old_db_name_len INT;\n" + "old_t_name_len INT;\n" + "new_db_name_len INT;\n" + "id_len INT;\n" + "found INT;\n" + "BEGIN\n" + "found := 1;\n" + "old_db_name_len := INSTR(:old_table_name, '/') - 1;\n" + "new_db_name_len := INSTR(:new_table_name, '/') - 1;\n" + "new_db_name := SUBSTR(:new_table_name, 0, new_db_name_len);\n" + "old_t_name_len := LENGTH(:old_table_name);\n" + "gen_constr_prefix := CONCAT(:old_table_name, '_ibfk_');\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = :old_table_name\n" + " AND TO_BINARY(FOR_NAME) = TO_BINARY(:old_table_name);\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE\n" + " UPDATE SYS_FOREIGN\n" + " SET FOR_NAME = :new_table_name\n" + " WHERE ID = foreign_id;\n" + " id_len := LENGTH(foreign_id);\n" + " IF (INSTR(foreign_id, '/') > 0) THEN\n" + " IF (INSTR(foreign_id,\n" + " gen_constr_prefix) > 0)\n" + " THEN\n" + " new_foreign_id :=\n" + " CONCAT(:new_table_name,\n" + " SUBSTR(foreign_id, old_t_name_len,\n" + " id_len - old_t_name_len));\n" + " ELSE\n" + " new_foreign_id :=\n" + " CONCAT(new_db_name,\n" + " SUBSTR(foreign_id,\n" + " old_db_name_len,\n" + " id_len - old_db_name_len));\n" + " END IF;\n" + " UPDATE SYS_FOREIGN\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " UPDATE SYS_FOREIGN_COLS\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " END IF;\n" + " END IF;\n" + "END LOOP;\n" + "UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name\n" + "WHERE REF_NAME = :old_table_name\n" + " AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);\n" + "END;\n" + , trx); - ut_a(thr = que_fork_start_command(graph)); + } else if (n_constraints_to_drop > 0) { + /* Drop some constraints of tmp tables. */ - que_run_threads(thr); + ulint db_name_len = dict_get_db_name_len(old_name) + 1; + char* db_name = mem_heap_strdupl(heap, old_name, + db_name_len); + ulint i; - err = trx->error_state; + for (i = 0; i < n_constraints_to_drop; i++) { + err = row_delete_constraint(constraints_to_drop[i], + db_name, heap, trx); + if (err != DB_SUCCESS) { + break; + } + } + } + +end: if (err != DB_SUCCESS) { if (err == DB_DUPLICATE_KEY) { ut_print_timestamp(stderr); @@ -3830,8 +3732,9 @@ row_rename_table_for_mysql( /* The following call will also rename the .ibd data file if the table is stored in a single-table tablespace */ - success = dict_table_rename_in_cache(table, new_name, + ibool success = dict_table_rename_in_cache(table, new_name, !new_is_tmp); + if (!success) { trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, FALSE, NULL); @@ -3879,20 +3782,16 @@ row_rename_table_for_mysql( ut_a(dict_table_rename_in_cache(table, old_name, FALSE)); trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); + trx_general_rollback_for_mysql(trx, FALSE, NULL); trx->error_state = DB_SUCCESS; } } + funct_exit: if (!recovering_temp_table) { row_mysql_unlock_data_dictionary(trx); } - if (graph) { - que_graph_free(graph); - } - if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 0809d2872a5..c0f906f4ed7 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -710,12 +710,17 @@ row_sel_get_clust_rec( if (!node->read_view) { /* Try to place a lock on the index record */ - /* If innodb_locks_unsafe_for_binlog option is used, + /* If innodb_locks_unsafe_for_binlog option is used + or this session is using READ COMMITTED isolation level we lock only the record, i.e., next-key locking is not used. */ ulint lock_type; + trx_t* trx; - if (srv_locks_unsafe_for_binlog) { + trx = thr_get_trx(thr); + + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { lock_type = LOCK_REC_NOT_GAP; } else { lock_type = LOCK_ORDINARY; @@ -1307,16 +1312,22 @@ rec_loop: if (!consistent_read) { - /* If innodb_locks_unsafe_for_binlog option is used, - we lock only the record, i.e., next-key locking is - not used. */ + /* If innodb_locks_unsafe_for_binlog option is used + or this session is using READ COMMITTED isolation + level, we lock only the record, i.e., next-key + locking is not used. */ rec_t* next_rec = page_rec_get_next(rec); ulint lock_type; + trx_t* trx; + + trx = thr_get_trx(thr); + offsets = rec_get_offsets(next_rec, index, offsets, ULINT_UNDEFINED, &heap); - if (srv_locks_unsafe_for_binlog) { + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { lock_type = LOCK_REC_NOT_GAP; } else { lock_type = LOCK_ORDINARY; @@ -1350,15 +1361,21 @@ rec_loop: if (!consistent_read) { /* Try to place a lock on the index record */ - /* If innodb_locks_unsafe_for_binlog option is used, + /* If innodb_locks_unsafe_for_binlog option is used + or this session is using READ COMMITTED isolation level, we lock only the record, i.e., next-key locking is not used. */ ulint lock_type; + trx_t* trx; + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); - if (srv_locks_unsafe_for_binlog) { + trx = thr_get_trx(thr); + + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { lock_type = LOCK_REC_NOT_GAP; } else { lock_type = LOCK_ORDINARY; @@ -1413,14 +1430,6 @@ rec_loop: /* Ok, no need to test end_conds or mix id */ - } else if (plan->mixed_index) { - /* We have to check if the record in a mixed cluster belongs - to this table */ - - if (!dict_is_mixed_table_rec(plan->table, rec)) { - - goto next_rec; - } } /* We are ready to look at a possible new index entry in the result @@ -1958,7 +1967,18 @@ fetch_step( if (sel_node->state != SEL_NODE_NO_MORE_ROWS) { - sel_assign_into_var_values(node->into_list, sel_node); + if (node->into_list) { + sel_assign_into_var_values(node->into_list, + sel_node); + } else { + void* ret = (*node->func->func)(sel_node, + node->func->arg); + + if (!ret) { + sel_node->state = + SEL_NODE_NO_MORE_ROWS; + } + } } thr->run_node = que_node_get_parent(node); @@ -1974,8 +1994,8 @@ fetch_step( sel_node->common.parent = node; if (sel_node->state == SEL_NODE_CLOSED) { - /* SQL error detected */ - fprintf(stderr, "SQL error %lu\n", (ulong)DB_ERROR); + fprintf(stderr, + "InnoDB: Error: fetch called on a closed cursor\n"); que_thr_handle_error(thr, DB_ERROR, NULL, 0); @@ -1987,6 +2007,76 @@ fetch_step( return(thr); } +/******************************************************************** +Sample callback function for fetch that prints each row.*/ + +void* +row_fetch_print( +/*============*/ + /* out: always returns non-NULL */ + void* row, /* in: sel_node_t* */ + void* user_arg) /* in: not used */ +{ + sel_node_t* node = row; + que_node_t* exp; + ulint i = 0; + + UT_NOT_USED(user_arg); + + fprintf(stderr, "row_fetch_print: row %p\n", row); + + exp = node->select_list; + + while (exp) { + dfield_t* dfield = que_node_get_val(exp); + dtype_t* type = dfield_get_type(dfield); + + fprintf(stderr, " column %lu:\n", (ulong)i); + + dtype_print(type); + fprintf(stderr, "\n"); + + ut_print_buf(stderr, dfield_get_data(dfield), + dfield_get_len(dfield)); + fprintf(stderr, "\n"); + + exp = que_node_get_next(exp); + i++; + } + + return((void*)42); +} + +/******************************************************************** +Callback function for fetch that stores an unsigned 4 byte integer to the +location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length += 4. */ + +void* +row_fetch_store_uint4( +/*==================*/ + /* out: always returns NULL */ + void* row, /* in: sel_node_t* */ + void* user_arg) /* in: data pointer */ +{ + sel_node_t* node = row; + ib_uint32_t* val = user_arg; + ulint tmp; + + dfield_t* dfield = que_node_get_val(node->select_list); + dtype_t* type = dfield_get_type(dfield); + ulint len = dfield_get_len(dfield); + + ut_a(dtype_get_mtype(type) == DATA_INT); + ut_a(dtype_get_prtype(type) & DATA_UNSIGNED); + ut_a(len == 4); + + tmp = mach_read_from_4(dfield_get_data(dfield)); + *val = tmp; + + return(NULL); +} + /*************************************************************** Prints a row in a select result. */ @@ -2397,18 +2487,16 @@ row_sel_field_store_in_mysql_format( } else if (templ->type == DATA_MYSQL) { memcpy(dest, data, len); -#if defined(UNIV_RELEASE_NOT_YET_STABLE) || defined(UNIV_DEBUG) - ut_a(templ->mysql_col_len >= len); - ut_a(templ->mbmaxlen >= templ->mbminlen); + ut_ad(templ->mysql_col_len >= len); + ut_ad(templ->mbmaxlen >= templ->mbminlen); - ut_a(templ->mbmaxlen > templ->mbminlen + ut_ad(templ->mbmaxlen > templ->mbminlen || templ->mysql_col_len == len); - ut_a(len * templ->mbmaxlen >= templ->mysql_col_len); -#endif /* UNIV_RELEASE_NOT_YET_STABLE || UNIV_DEBUG */ /* The following assertion would fail for old tables containing UTF-8 ENUM columns due to Bug #9526. */ ut_ad(!templ->mbmaxlen || !(templ->mysql_col_len % templ->mbmaxlen)); + ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len); if (templ->mbminlen != templ->mbmaxlen) { /* Pad with spaces. This undoes the stripping @@ -2418,15 +2506,13 @@ row_sel_field_store_in_mysql_format( memset(dest + len, 0x20, templ->mysql_col_len - len); } } else { -#if defined(UNIV_RELEASE_NOT_YET_STABLE) || defined(UNIV_DEBUG) - ut_a(templ->type == DATA_CHAR + ut_ad(templ->type == DATA_CHAR || templ->type == DATA_FIXBINARY /*|| templ->type == DATA_SYS_CHILD || templ->type == DATA_SYS*/ || templ->type == DATA_FLOAT || templ->type == DATA_DOUBLE || templ->type == DATA_DECIMAL); -#endif /* UNIV_RELEASE_NOT_YET_STABLE || UNIV_DEBUG */ ut_ad(templ->mysql_col_len == len); memcpy(dest, data, len); @@ -3210,11 +3296,13 @@ stderr); } /* Reset the new record lock info if srv_locks_unsafe_for_binlog - is set. Then we are able to remove the record locks set here on an - individual row. */ + is set or session is using a READ COMMITED isolation level. Then + we are able to remove the record locks set here on an individual + row. */ - if (srv_locks_unsafe_for_binlog - && prebuilt->select_lock_type != LOCK_NONE) { + if ((srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { trx_reset_new_rec_lock_info(trx); } @@ -3582,13 +3670,15 @@ rec_loop: if (page_rec_is_supremum(rec)) { if (set_also_gap_locks - && !srv_locks_unsafe_for_binlog - && prebuilt->select_lock_type != LOCK_NONE) { + && !(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a lock on the index record */ - /* If innodb_locks_unsafe_for_binlog option is used, - we do not lock gaps. Supremum record is really + /* If innodb_locks_unsafe_for_binlog option is used + or this session is using a READ COMMITTED isolation + level we do not lock gaps. Supremum record is really a gap and therefore we do not set locks there. */ offsets = rec_get_offsets(rec, index, offsets, @@ -3708,12 +3798,14 @@ wrong_offs: if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) { if (set_also_gap_locks - && !srv_locks_unsafe_for_binlog - && prebuilt->select_lock_type != LOCK_NONE) { + && !(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a gap lock on the index record only if innodb_locks_unsafe_for_binlog - option is not set */ + option is not set or this session is not + using a READ COMMITTED isolation level. */ err = sel_set_rec_lock(rec, index, offsets, prebuilt->select_lock_type, @@ -3739,12 +3831,14 @@ wrong_offs: if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, offsets)) { if (set_also_gap_locks - && !srv_locks_unsafe_for_binlog - && prebuilt->select_lock_type != LOCK_NONE) { + && !(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a gap lock on the index record only if innodb_locks_unsafe_for_binlog - option is not set */ + option is not set or this session is not + using a READ COMMITTED isolation level. */ err = sel_set_rec_lock(rec, index, offsets, prebuilt->select_lock_type, @@ -3775,16 +3869,18 @@ wrong_offs: is a non-delete marked record, then it is enough to lock its existence with LOCK_REC_NOT_GAP. */ - /* If innodb_locks_unsafe_for_binlog option is used, - we lock only the record, i.e., next-key locking is + /* If innodb_locks_unsafe_for_binlog option is used + or this session is using a READ COMMITED isolation + level we lock only the record, i.e., next-key locking is not used. */ ulint lock_type; if (!set_also_gap_locks - || srv_locks_unsafe_for_binlog - || (unique_search && !UNIV_UNLIKELY( - rec_get_deleted_flag(rec, comp)))) { + || srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED + || (unique_search + && !UNIV_UNLIKELY(rec_get_deleted_flag(rec, comp)))) { goto no_gap_lock; } else { @@ -3943,9 +4039,10 @@ no_gap_lock: /* The record is delete-marked: we can skip it */ - if (srv_locks_unsafe_for_binlog - && prebuilt->select_lock_type != LOCK_NONE - && !did_semi_consistent_read) { + if ((srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE + && !did_semi_consistent_read) { /* No need to keep a lock on a delete-marked record if we do not want to use next-key locking. */ @@ -3996,8 +4093,9 @@ requires_clust_rec: /* The record is delete marked: we can skip it */ - if (srv_locks_unsafe_for_binlog - && prebuilt->select_lock_type != LOCK_NONE) { + if ((srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { /* No need to keep a lock on a delete-marked record if we do not want to use next-key @@ -4117,8 +4215,9 @@ next_rec: } did_semi_consistent_read = FALSE; - if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog) - && prebuilt->select_lock_type != LOCK_NONE) { + if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { trx_reset_new_rec_lock_info(trx); } @@ -4206,7 +4305,11 @@ lock_wait_or_error: sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, pcur, moves_up, &mtr); - if (srv_locks_unsafe_for_binlog && !same_user_rec) { + + if ((srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && !same_user_rec) { + /* Since we were not able to restore the cursor on the same user record, we cannot use row_unlock_for_mysql() to unlock any records, and diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 23be601a17b..4023283a60c 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -28,6 +28,7 @@ Created 12/27/1996 Heikki Tuuri #include "log0log.h" #include "pars0sym.h" #include "eval0eval.h" +#include "buf0lru.h" /* What kind of latch and lock can we assume when the control comes to @@ -869,6 +870,10 @@ row_upd_index_replace_new_col_vals_index_pos( upd_t* update, /* in: an update vector built for the index so that the field number in an upd_field is the index position */ + ibool order_only, + /* in: if TRUE, limit the replacement to + ordering fields of index; note that this + does not work for non-clustered indexes. */ mem_heap_t* heap) /* in: memory heap to which we allocate and copy the new values, set this as NULL if you do not want allocation */ @@ -879,13 +884,20 @@ row_upd_index_replace_new_col_vals_index_pos( dfield_t* new_val; ulint j; ulint i; + ulint n_fields; dtype_t* cur_type; ut_ad(index); dtuple_set_info_bits(entry, update->info_bits); - for (j = 0; j < dict_index_get_n_fields(index); j++) { + if (order_only) { + n_fields = dict_index_get_n_unique(index); + } else { + n_fields = dict_index_get_n_fields(index); + } + + for (j = 0; j < n_fields; j++) { field = dict_index_get_nth_field(index, j); @@ -1530,6 +1542,10 @@ row_upd_clust_rec( return(err); } + if (buf_LRU_buf_pool_running_out()) { + + return(DB_LOCK_TABLE_FULL); + } /* We may have to modify the tree structure: do a pessimistic descent down the index tree */ diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 1256dd21c87..fe1eeab9c3f 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1713,6 +1713,8 @@ srv_printf_innodb_monitor( "; in additional pool allocated " ULINTPF "\n", ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); + fprintf(file, "Dictionary memory allocated " ULINTPF "\n", + dict_sys->size); if (srv_use_awe) { fprintf(file, diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c index 1f3d6df0403..fb7ec4cc78b 100644 --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -524,7 +524,7 @@ sync_array_cell_print( "Last time reserved in file %s line %lu, " #endif /* UNIV_SYNC_DEBUG */ "waiters flag %lu\n", - mutex, mutex->cfile_name, (ulong) mutex->cline, + (void*) mutex, mutex->cfile_name, (ulong) mutex->cline, (ulong) mutex->lock_word, #ifdef UNIV_SYNC_DEBUG mutex->file_name, (ulong) mutex->line, @@ -539,7 +539,7 @@ sync_array_cell_print( fprintf(file, " RW-latch at %p created in file %s line %lu\n", - rwlock, rwlock->cfile_name, + (void*) rwlock, rwlock->cfile_name, (ulong) rwlock->cline); if (rwlock->writer != RW_LOCK_NOT_LOCKED) { fprintf(file, @@ -670,7 +670,6 @@ sync_array_detect_deadlock( rw_lock_debug_t*debug; ut_a(arr && start && cell); - ut_ad(cell->state == SC_RESERVED); ut_ad(cell->wait_object); ut_ad(os_thread_get_curr_id() == start->thread); ut_ad(depth < 100); @@ -703,7 +702,7 @@ sync_array_detect_deadlock( if (ret) { fprintf(stderr, "Mutex %p owned by thread %lu file %s line %lu\n", - mutex, + (void*) mutex, (ulong) os_thread_pf(mutex->thread_id), mutex->file_name, (ulong) mutex->line); sync_array_cell_print(stderr, cell); @@ -740,7 +739,8 @@ sync_array_detect_deadlock( thread, debug->pass, depth); if (ret) { print: - fprintf(stderr, "rw-lock %p ", lock); + fprintf(stderr, "rw-lock %p ", + (void*) lock); sync_array_cell_print(stderr, cell); rw_lock_debug_print(debug); return(TRUE); diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c index b33c1553bae..673e1080d89 100644 --- a/storage/innobase/sync/sync0rw.c +++ b/storage/innobase/sync/sync0rw.c @@ -246,7 +246,7 @@ lock_loop: if (srv_print_latch_waits) { fprintf(stderr, "Thread %lu spin wait rw-s-lock at %p cfile %s cline %lu rnds %lu\n", - (ulong) os_thread_pf(os_thread_get_curr_id()), lock, + (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) lock, lock->cfile_name, (ulong) lock->cline, (ulong) i); } @@ -277,7 +277,8 @@ lock_loop: fprintf(stderr, "Thread %lu OS wait rw-s-lock at %p cfile %s cline %lu\n", os_thread_pf(os_thread_get_curr_id()), - lock, lock->cfile_name, (ulong) lock->cline); + (void*) lock, lock->cfile_name, + (ulong) lock->cline); } rw_s_system_call_count++; @@ -495,8 +496,8 @@ lock_loop: if (srv_print_latch_waits) { fprintf(stderr, "Thread %lu spin wait rw-x-lock at %p cfile %s cline %lu rnds %lu\n", - os_thread_pf(os_thread_get_curr_id()), lock, - lock->cfile_name, (ulong) lock->cline, (ulong) i); + os_thread_pf(os_thread_get_curr_id()), (void*) lock, + lock->cfile_name, (ulong) lock->cline, (ulong) i); } rw_x_spin_wait_count++; @@ -528,8 +529,8 @@ lock_loop: if (srv_print_latch_waits) { fprintf(stderr, "Thread %lu OS wait for rw-x-lock at %p cfile %s cline %lu\n", - os_thread_pf(os_thread_get_curr_id()), lock, - lock->cfile_name, (ulong) lock->cline); + os_thread_pf(os_thread_get_curr_id()), (void*) lock, + lock->cfile_name, (ulong) lock->cline); } rw_x_system_call_count++; @@ -787,7 +788,7 @@ rw_lock_list_print_info(void) || (rw_lock_get_reader_count(lock) != 0) || (rw_lock_get_waiters(lock) != 0)) { - fprintf(stderr, "RW-LOCK: %p ", lock); + fprintf(stderr, "RW-LOCK: %p ", (void*) lock); if (rw_lock_get_waiters(lock)) { fputs(" Waiters for the lock exist\n", stderr); @@ -823,7 +824,7 @@ rw_lock_print( fprintf(stderr, "-------------\n" "RW-LATCH INFO\n" - "RW-LATCH: %p ", lock); + "RW-LATCH: %p ", (void*) lock); if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) || (rw_lock_get_reader_count(lock) != 0) diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 86fa66d5112..6354830df70 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -423,7 +423,7 @@ spin_loop: #ifdef UNIV_SRV_PRINT_LATCH_WAITS fprintf(stderr, "Thread %lu spin wait mutex at %p cfile %s cline %lu rnds %lu\n", - (ulong) os_thread_pf(os_thread_get_curr_id()), mutex, + (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex, mutex->cfile_name, (ulong) mutex->cline, (ulong) i); #endif @@ -485,7 +485,7 @@ spin_loop: fprintf(stderr, "Thread %lu spin wait succeeds at 2:" " mutex at %p\n", (ulong) os_thread_pf(os_thread_get_curr_id()), - mutex); + (void*) mutex); #endif goto finish_timing; @@ -503,7 +503,7 @@ spin_loop: #ifdef UNIV_SRV_PRINT_LATCH_WAITS fprintf(stderr, "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n", - (ulong) os_thread_pf(os_thread_get_curr_id()), mutex, + (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex, mutex->cfile_name, (ulong) mutex->cline, (ulong) i); #endif @@ -666,7 +666,7 @@ mutex_list_print_info(void) &thread_id); fprintf(stderr, "Locked mutex: addr %p thread %ld file %s line %ld\n", - mutex, os_thread_pf(thread_id), + (void*) mutex, os_thread_pf(thread_id), file_name, line); } @@ -852,10 +852,10 @@ sync_thread_levels_g( fprintf(stderr, "InnoDB: Locked mutex: addr %p thread %ld file %s line %ld\n", - mutex, os_thread_pf(thread_id), file_name, (ulong) line); + (void*) mutex, os_thread_pf(thread_id), file_name, (ulong) line); #else /* UNIV_SYNC_DEBUG */ fprintf(stderr, - "InnoDB: Locked mutex: addr %p\n", mutex); + "InnoDB: Locked mutex: addr %p\n", (void*) mutex); #endif /* UNIV_SYNC_DEBUG */ } else { fputs("Not locked\n", stderr); diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 90d6d92c09e..a3115e332cd 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -366,8 +366,6 @@ trx_free_for_mysql( /*===============*/ trx_t* trx) /* in, own: trx object */ { - thr_local_free(trx->mysql_thread_id); - mutex_enter(&kernel_mutex); UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx); @@ -1770,6 +1768,9 @@ trx_print( fprintf(f, "%lu lock struct(s), heap size %lu", (ulong) UT_LIST_GET_LEN(trx->trx_locks), (ulong) mem_heap_get_size(trx->lock_heap)); + + fprintf(f, "%lu row lock(s)", + (ulong) lock_number_of_rows_locked(trx)); } if (trx->has_search_latch) { diff --git a/storage/innobase/ut/Makefile.am b/storage/innobase/ut/Makefile.am index 2fdbb99e0f3..c833a6d5a4c 100644 --- a/storage/innobase/ut/Makefile.am +++ b/storage/innobase/ut/Makefile.am @@ -19,6 +19,6 @@ include ../include/Makefile.i noinst_LIBRARIES = libut.a -libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c +libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c EXTRA_PROGRAMS = diff --git a/storage/innobase/ut/ut0mem.c b/storage/innobase/ut/ut0mem.c index 345c14e00f9..4358edba8c0 100644 --- a/storage/innobase/ut/ut0mem.c +++ b/storage/innobase/ut/ut0mem.c @@ -437,3 +437,96 @@ ut_memcpyq( return(dest); } + +/************************************************************************** +Return the number of times s2 occurs in s1. Overlapping instances of s2 +are only counted once. */ + +ulint +ut_strcount( +/*========*/ + /* out: the number of times s2 occurs in s1 */ + const char* s1, /* in: string to search in */ + const char* s2) /* in: string to search for */ +{ + ulint count = 0; + ulint len = strlen(s2); + + if (len == 0) { + + return(0); + } + + for (;;) { + s1 = strstr(s1, s2); + + if (!s1) { + + break; + } + + count++; + s1 += len; + } + + return(count); +} + +/************************************************************************** +Replace every occurrence of s1 in str with s2. Overlapping instances of s1 +are only replaced once. */ + +char * +ut_strreplace( +/*==========*/ + /* out, own: modified string, must be + freed with mem_free() */ + const char* str, /* in: string to operate on */ + const char* s1, /* in: string to replace */ + const char* s2) /* in: string to replace s1 with */ +{ + char* new_str; + char* ptr; + const char* str_end; + ulint str_len = strlen(str); + ulint s1_len = strlen(s1); + ulint s2_len = strlen(s2); + ulint count = 0; + int len_delta = (int)s2_len - (int)s1_len; + + str_end = str + str_len; + + if (len_delta <= 0) { + len_delta = 0; + } else { + count = ut_strcount(str, s1); + } + + new_str = mem_alloc(str_len + count * len_delta + 1); + ptr = new_str; + + while (str) { + const char* next = strstr(str, s1); + + if (!next) { + next = str_end; + } + + memcpy(ptr, str, next - str); + ptr += next - str; + + if (next == str_end) { + + break; + } + + memcpy(ptr, s2, s2_len); + ptr += s2_len; + + str = next + s1_len; + } + + *ptr = '\0'; + + return(new_str); +} diff --git a/storage/innobase/ut/ut0vec.c b/storage/innobase/ut/ut0vec.c new file mode 100644 index 00000000000..3f61c8c8386 --- /dev/null +++ b/storage/innobase/ut/ut0vec.c @@ -0,0 +1,54 @@ +#include "ut0vec.h" +#ifdef UNIV_NONINL +#include "ut0vec.ic" +#endif +#include <string.h> + +/******************************************************************** +Create a new vector with the given initial size. */ + +ib_vector_t* +ib_vector_create( +/*=============*/ + /* out: vector */ + mem_heap_t* heap, /* in: heap */ + ulint size) /* in: initial size */ +{ + ib_vector_t* vec; + + ut_a(size > 0); + + vec = mem_heap_alloc(heap, sizeof(*vec)); + + vec->heap = heap; + vec->data = mem_heap_alloc(heap, sizeof(void*) * size); + vec->used = 0; + vec->total = size; + + return(vec); +} + +/******************************************************************** +Push a new element to the vector, increasing its size if necessary. */ + +void +ib_vector_push( +/*===========*/ + ib_vector_t* vec, /* in: vector */ + void* elem) /* in: data element */ +{ + if (vec->used >= vec->total) { + void** new_data; + ulint new_total = vec->total * 2; + + new_data = mem_heap_alloc(vec->heap, + sizeof(void*) * new_total); + memcpy(new_data, vec->data, sizeof(void*) * vec->total); + + vec->data = new_data; + vec->total = new_total; + } + + vec->data[vec->used] = elem; + vec->used++; +} |