From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 761162CCC3 for ; Sat, 31 Mar 2018 00:24:16 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Cy8Czg1DS8YH for ; Sat, 31 Mar 2018 00:24:16 -0400 (EDT) Received: from smtp63.i.mail.ru (smtp63.i.mail.ru [217.69.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id F1E602CC28 for ; Sat, 31 Mar 2018 00:24:14 -0400 (EDT) From: Kirill Yukhin Subject: [tarantool-patches] [PATCH] sql: move default col values to Tarantool's core Date: Sat, 31 Mar 2018 07:24:02 +0300 Message-Id: <20180331042402.25814-1-kyukhin@tarantool.org> In-Reply-To: <20180331035500.u75xt6efbwtoxc5a@tarantool.org> References: <20180331035500.u75xt6efbwtoxc5a@tarantool.org> Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: v.shpilevoy@tarantool.org Cc: tarantool-patches@freelists.org Extract expressions parsing into separate routine to allow Tarantool's backend compile DEFAULT statements w/o SQL machinery at all. So far, for DEFAULT values no context is needed: only constant expressions and built-ins are allowed. In future, table context will be added to allow use column values for CHECK constraint expressions. Move DEFAULT string value to space_def. Move compiled expresion to field_def as well. Reason not to move compiled expression to tuple_field as follows: we do not want to engage parser during tuple validation. So, do it in alter.cc. In order to allow expression duplication in alter.cc: expose those routines from expr.c and make their names correspond to coding style. Since recovery is performed before SQL fronend initialization: split it into two pieces: 1. create SQL handler, enable all subsystems 2. Do recovery. This will allow to run parser during recovery, since it needs db handle so far. Part of #3235 --- src/CMakeLists.txt | 2 +- src/box/alter.cc | 33 +- src/box/box.cc | 3 +- src/box/field_def.c | 5 +- src/box/field_def.h | 4 + src/box/space_def.c | 133 ++++++-- src/box/space_def.h | 10 +- src/box/sql.c | 98 +++++- src/box/sql.h | 96 +++++- src/box/sql/build.c | 18 +- src/box/sql/delete.c | 12 +- src/box/sql/expr.c | 127 +++---- src/box/sql/fkey.c | 13 +- src/box/sql/insert.c | 34 +- src/box/sql/main.c | 15 - src/box/sql/parse.c | 876 ++++++++++++++++++++++++------------------------ src/box/sql/parse.y | 32 +- src/box/sql/resolve.c | 12 +- src/box/sql/select.c | 28 +- src/box/sql/sqliteInt.h | 11 +- src/box/sql/tokenize.c | 109 ++++++ src/box/sql/trigger.c | 12 +- src/box/sql/update.c | 2 +- src/box/sql/wherecode.c | 2 +- src/box/sql/whereexpr.c | 6 +- 25 files changed, 1032 insertions(+), 661 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8ab09e9..eae40c3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -268,7 +268,7 @@ add_executable( ${LIBUTIL_FREEBSD_SRC}/flopen.c ${LIBUTIL_FREEBSD_SRC}/pidfile.c) -add_dependencies(tarantool build_bundled_libs preprocess_exports) +add_dependencies(tarantool build_bundled_libs preprocess_exports sql) # Re-link if exports changed set_target_properties(tarantool PROPERTIES LINK_DEPENDS ${exports_file}) diff --git a/src/box/alter.cc b/src/box/alter.cc index f40290b..08c1220 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -52,6 +52,7 @@ #include "memtx_tuple.h" #include "version.h" #include "sequence.h" +#include "sql.h" /** * chap-sha1 of empty string, i.e. @@ -403,6 +404,19 @@ field_def_decode(struct field_def *field, const char **data, tt_sprintf("collation is reasonable only for " "string, scalar and any fields")); } + + if (field->default_value != NULL) { + struct Expr *expr = NULL; + char *err = NULL; + sql_expr_compile(sql_get(), + field->default_value, + &expr, + &err); + if (err != NULL) + tnt_raise(ClientError, ER_SQL_EXECUTE, field->default_value); + assert(expr != NULL); + field->default_value_expr = expr; + } } /** @@ -1416,6 +1430,11 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) struct tuple *old_tuple = stmt->old_tuple; struct tuple *new_tuple = stmt->new_tuple; struct region *region = &fiber()->gc; + struct space_def *def = NULL; + auto def_guard = make_scoped_guard([&] { + if (def != NULL) + space_def_delete(def); + }); /* * Things to keep in mind: * - old_tuple is set only in case of UPDATE. For INSERT @@ -1434,12 +1453,9 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) BOX_SPACE_FIELD_ID); struct space *old_space = space_by_id(old_id); if (new_tuple != NULL && old_space == NULL) { /* INSERT */ - struct space_def *def = - space_def_new_from_tuple(new_tuple, ER_CREATE_SPACE, - region); + def = space_def_new_from_tuple(new_tuple, ER_CREATE_SPACE, + region); access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_C, true); - auto def_guard = - make_scoped_guard([=] { space_def_delete(def); }); RLIST_HEAD(empty_list); struct space *space = space_new_xc(def, &empty_list); /** @@ -1494,12 +1510,9 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) txn_on_rollback(txn, on_rollback); } else { /* UPDATE, REPLACE */ assert(old_space != NULL && new_tuple != NULL); - struct space_def *def = - space_def_new_from_tuple(new_tuple, ER_ALTER_SPACE, - region); + def = space_def_new_from_tuple(new_tuple, ER_ALTER_SPACE, + region); access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_A, true); - auto def_guard = - make_scoped_guard([=] { space_def_delete(def); }); /* * Check basic options. Assume the space to be * empty, because we can not calculate here diff --git a/src/box/box.cc b/src/box/box.cc index a3bbdfc..290d18c 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -1731,6 +1731,7 @@ box_cfg_xc(void) replication_init(); port_init(); iproto_init(); + sql_init(); wal_thread_start(); title("loading"); @@ -1927,7 +1928,7 @@ box_cfg_xc(void) /* Follow replica */ replicaset_follow(); - sql_init(); + sql_load_schema(); say_info("ready to accept requests"); diff --git a/src/box/field_def.c b/src/box/field_def.c index 1510509..010b3b7 100644 --- a/src/box/field_def.c +++ b/src/box/field_def.c @@ -94,6 +94,7 @@ const struct opt_def field_def_reg[] = { OPT_DEF_ENUM("nullable_action", on_conflict_action, struct field_def, nullable_action, NULL), OPT_DEF("collation", OPT_UINT32, struct field_def, coll_id), + OPT_DEF("default", OPT_STRPTR, struct field_def, default_value), OPT_END, }; @@ -102,7 +103,9 @@ const struct field_def field_def_default = { .name = NULL, .is_nullable = false, .nullable_action = ON_CONFLICT_ACTION_DEFAULT, - .coll_id = COLL_NONE + .coll_id = COLL_NONE, + .default_value = NULL, + .default_value_expr = NULL }; enum field_type diff --git a/src/box/field_def.h b/src/box/field_def.h index e7be06a..dfc1950 100644 --- a/src/box/field_def.h +++ b/src/box/field_def.h @@ -110,6 +110,10 @@ struct field_def { enum on_conflict_action nullable_action; /** Collation ID for string comparison. */ uint32_t coll_id; + /** 0-terminated SQL expression for DEFAULT value. */ + char *default_value; + /** AST for parsed default value. */ + struct Expr *default_value_expr; }; #if defined(__cplusplus) diff --git a/src/box/space_def.c b/src/box/space_def.c index 1b3c305..d1bee16 100644 --- a/src/box/space_def.c +++ b/src/box/space_def.c @@ -32,6 +32,7 @@ #include "space_def.h" #include "diag.h" #include "error.h" +#include "sql.h" const struct space_opts space_opts_default = { /* .temporary = */ false, @@ -49,34 +50,48 @@ const struct opt_def space_opts_reg[] = { /** * Size of the space_def. * @param name_len Length of the space name. - * @param field_names_size Size of all names. + * @param fields Fields array of space format. * @param field_count Space field count. * @param[out] names_offset Offset from the beginning of a def to * a field names memory. * @param[out] fields_offset Offset from the beginning of a def to * a fields array. + * @param[out] def_expr_offset Offset from the beginning of a def + * to a def_value_expr array. * @retval Size in bytes. */ static inline size_t -space_def_sizeof(uint32_t name_len, uint32_t field_names_size, +space_def_sizeof(uint32_t name_len, const struct field_def *fields, uint32_t field_count, uint32_t *names_offset, - uint32_t *fields_offset) + uint32_t *fields_offset, uint32_t *def_expr_offset) { + uint32_t field_strs_size = 0; + uint32_t def_exprs_size = 0; + for (uint32_t i = 0; i < field_count; ++i) { + field_strs_size += strlen(fields[i].name) + 1; + if (fields[i].default_value != NULL) { + int len = strlen(fields[i].default_value); + field_strs_size += len + 1; + if (fields[i].default_value_expr != NULL) { + struct Expr *e = fields[i].default_value_expr; + def_exprs_size += sql_expr_sizeof(e, 0); + } + } + } + *fields_offset = sizeof(struct space_def) + name_len + 1; *names_offset = *fields_offset + field_count * sizeof(struct field_def); - return *names_offset + field_names_size; + *def_expr_offset = *names_offset + field_strs_size; + return *def_expr_offset + def_exprs_size; } struct space_def * space_def_dup(const struct space_def *src) { - uint32_t names_offset, fields_offset; - uint32_t field_names_size = 0; - for (uint32_t i = 0; i < src->field_count; ++i) - field_names_size += strlen(src->fields[i].name) + 1; - size_t size = space_def_sizeof(strlen(src->name), field_names_size, - src->field_count, &names_offset, - &fields_offset); + uint32_t strs_offset, fields_offset, def_expr_offset; + size_t size = space_def_sizeof(strlen(src->name), src->fields, + src->field_count, &strs_offset, + &fields_offset, &def_expr_offset); struct space_def *ret = (struct space_def *) malloc(size); if (ret == NULL) { diag_set(OutOfMemory, size, "malloc", "ret"); @@ -92,12 +107,37 @@ space_def_dup(const struct space_def *src) return NULL; } } - char *name_pos = (char *)ret + names_offset; + char *strs_pos = (char *)ret + strs_offset; + char *expr_pos = (char *)ret + def_expr_offset; if (src->field_count > 0) { ret->fields = (struct field_def *)((char *)ret + fields_offset); for (uint32_t i = 0; i < src->field_count; ++i) { - ret->fields[i].name = name_pos; - name_pos += strlen(name_pos) + 1; + ret->fields[i].name = strs_pos; + strs_pos += strlen(strs_pos) + 1; + if (src->fields[i].default_value != NULL) { + ret->fields[i].default_value = strs_pos; + strs_pos += strlen(strs_pos) + 1; + + struct Expr *def_expr; + def_expr = src->fields[i].default_value_expr; + if (def_expr != NULL) { + struct Expr *e = NULL; + char *expr_pos_old = expr_pos; + e = sql_expr_dup(sql_get(), + def_expr, + 0, &expr_pos); + /* Note: due to SQL legacy + * duplicactor pointer is + * not promoted for + * REDUCED exprs. Will be + * fixed w/ Expt + * allocation refactoring. + */ + assert(expr_pos_old == expr_pos); + expr_pos += sql_expr_sizeof(e, 0); + ret->fields[i].default_value_expr = e; + } + } } } tuple_dictionary_ref(ret->dict); @@ -111,12 +151,10 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count, const struct space_opts *opts, const struct field_def *fields, uint32_t field_count) { - uint32_t field_names_size = 0; - for (uint32_t i = 0; i < field_count; ++i) - field_names_size += strlen(fields[i].name) + 1; - uint32_t names_offset, fields_offset; - size_t size = space_def_sizeof(name_len, field_names_size, field_count, - &names_offset, &fields_offset); + uint32_t strs_offset, fields_offset, def_expr_offset; + size_t size = space_def_sizeof(name_len, fields, field_count, + &strs_offset, &fields_offset, + &def_expr_offset); struct space_def *def = (struct space_def *) malloc(size); if (def == NULL) { diag_set(OutOfMemory, size, "malloc", "def"); @@ -147,18 +185,49 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count, } } def->field_count = field_count; - if (field_count == 0) { + if (field_count == 0) def->fields = NULL; - } else { - char *name_pos = (char *)def + names_offset; + else { + char *strs_pos = (char *)def + strs_offset; + char *expr_pos = (char *)def + def_expr_offset; def->fields = (struct field_def *)((char *)def + fields_offset); for (uint32_t i = 0; i < field_count; ++i) { def->fields[i] = fields[i]; - def->fields[i].name = name_pos; + def->fields[i].name = strs_pos; uint32_t len = strlen(fields[i].name); memcpy(def->fields[i].name, fields[i].name, len); def->fields[i].name[len] = 0; - name_pos += len + 1; + strs_pos += len + 1; + + if (fields[i].default_value != NULL) { + def->fields[i].default_value = strs_pos; + len = strlen(fields[i].default_value); + memcpy(def->fields[i].default_value, + fields[i].default_value, len); + def->fields[i].default_value[len] = 0; + strs_pos += len + 1; + + struct Expr *def_expr_ast; + def_expr_ast = fields[i].default_value_expr; + if (def_expr_ast != NULL) { + struct Expr *expr; + char *expr_pos_old = expr_pos; + assert(sql_get() != NULL); + expr = sql_expr_dup(sql_get(), + def_expr_ast, + 0, &expr_pos); + /* Note: due to SQL legacy + * duplicactor pointer is + * not promoted for + * REDUCED exprs. Will be + * fixed w/ Expt + * allocation refactoring. + */ + assert(expr_pos_old == expr_pos); + expr_pos += sql_expr_sizeof(expr, 0); + def->fields[i].default_value_expr = expr; + } + } } } return def; @@ -217,3 +286,17 @@ space_def_check_compatibility(const struct space_def *old_def, return 0; } +void +space_def_delete(struct space_def *def) +{ + space_opts_destroy(&def->opts); + tuple_dictionary_unref(def->dict); + for (uint32_t i = 0; i < def->field_count; ++i) { + if (def->fields[i].default_value_expr != NULL) { + sql_expr_free(sql_get(), + def->fields[i].default_value_expr, true); + } + } + TRASH(def); + free(def); +} diff --git a/src/box/space_def.h b/src/box/space_def.h index b8d0bf8..7722738 100644 --- a/src/box/space_def.h +++ b/src/box/space_def.h @@ -115,14 +115,8 @@ struct space_def { * Delete the space_def object. * @param def Def to delete. */ -static inline void -space_def_delete(struct space_def *def) -{ - space_opts_destroy(&def->opts); - tuple_dictionary_unref(def->dict); - TRASH(def); - free(def); -} +void +space_def_delete(struct space_def *def); /** * Duplicate space_def object. diff --git a/src/box/sql.c b/src/box/sql.c index 6d8ef9a..ffa488a 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -56,7 +56,7 @@ #include "xrow.h" #include "iproto_constants.h" -static sqlite3 *db; +static sqlite3 *db = NULL; static const char nil_key[] = { 0x90 }; /* Empty MsgPack array. */ @@ -80,6 +80,27 @@ sql_init() } void +sql_load_schema() +{ + int rc; + struct session *user_session = current_session(); + int commit_internal = !(user_session->sql_flags + & SQLITE_InternChanges); + + assert(db->init.busy == 0); + db->init.busy = 1; + db->pSchema = sqlite3SchemaCreate(db); + rc = sqlite3InitDatabase(db); + if (rc != SQLITE_OK) { + sqlite3SchemaClear(db); + panic("failed to initialize SQL subsystem"); + } + db->init.busy = 0; + if (rc == SQLITE_OK && commit_internal) + sqlite3CommitInternalChanges(); +} + +void sql_free() { sqlite3_close(db); db = NULL; @@ -417,6 +438,9 @@ int tarantoolSqlite3EphemeralCreate(BtCursor *pCur, uint32_t field_count, { assert(pCur); assert(pCur->curFlags & BTCF_TEphemCursor); + struct key_def *ephemer_key_def = NULL; + struct index_def *ephemer_index_def = NULL; + struct space *ephemer_new_space = NULL; struct space_def *ephemer_space_def = space_def_new(0 /* space id */, 0 /* user id */, field_count, @@ -425,8 +449,13 @@ int tarantoolSqlite3EphemeralCreate(BtCursor *pCur, uint32_t field_count, &space_opts_default, &field_def_default, 0 /* length of field_def */); - struct key_def *ephemer_key_def = key_def_new(field_count); - assert(ephemer_key_def); + if (ephemer_space_def == NULL) + goto err; + + ephemer_key_def = key_def_new(field_count); + if (ephemer_key_def == NULL) + goto err; + for (uint32_t part = 0; part < field_count; ++part) { key_def_set_part(ephemer_key_def, part /* part no */, part /* filed no */, @@ -435,32 +464,45 @@ int tarantoolSqlite3EphemeralCreate(BtCursor *pCur, uint32_t field_count, aColl /* coll */); } - struct index_def *ephemer_index_def = + ephemer_index_def = index_def_new(0 /*space id */, 0 /* index id */, "ephemer_idx", strlen("ephemer_idx"), TREE, &index_opts_default, ephemer_key_def, NULL /* pk def */); + if (ephemer_index_def == NULL) + goto err; + struct rlist key_list; rlist_create(&key_list); rlist_add_entry(&key_list, ephemer_index_def, link); - struct space *ephemer_new_space = space_new_ephemeral(ephemer_space_def, - &key_list); - if (ephemer_new_space == NULL) { - diag_log(); - return SQL_TARANTOOL_ERROR; - } + ephemer_new_space = space_new_ephemeral(ephemer_space_def, &key_list); + if (ephemer_new_space == NULL) + goto err; + struct ta_cursor *c = NULL; c = cursor_create(c, field_count /* key size */); - if (!c) { - space_delete(ephemer_new_space); - return SQLITE_NOMEM; - } + if (!c) + goto err; c->ephem_space = ephemer_new_space; pCur->pTaCursor = c; int unused; return tarantoolSqlite3First(pCur, &unused); + +err: + if (ephemer_space_def != NULL) + space_def_delete(ephemer_space_def); + if (ephemer_key_def != NULL) + key_def_delete(ephemer_key_def); + if (ephemer_index_def != NULL) + index_def_delete(ephemer_index_def); + if(ephemer_space_def != NULL) + space_def_delete(ephemer_space_def); + if(ephemer_new_space != NULL) + space_delete(ephemer_new_space); + diag_log(); + return SQL_TARANTOOL_ERROR; } /* @@ -1546,11 +1588,17 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf) for (i = 0; i < n; i++) { const char *t; struct coll *coll = NULL; + struct Expr *def = aCol[i].pDflt; if (aCol[i].zColl != NULL && strcasecmp(aCol[i].zColl, "binary") != 0) { coll = sqlite3FindCollSeq(aCol[i].zColl); } - p = enc->encode_map(p, coll ? 5 : 4); + int base_len = 4; + if (coll != NULL) + base_len += 1; + if (def != NULL) + base_len += 1; + p = enc->encode_map(p, base_len); p = enc->encode_str(p, "name", 4); p = enc->encode_str(p, aCol[i].zName, strlen(aCol[i].zName)); p = enc->encode_str(p, "type", 4); @@ -1572,6 +1620,12 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf) p = enc->encode_str(p, "collation", strlen("collation")); p = enc->encode_uint(p, coll->id); } + if (def != NULL) { + assert((def->flags & EP_IntValue) == 0); + assert(def->u.zToken != NULL); + p = enc->encode_str(p, "default", strlen("default")); + p = enc->encode_str(p, def->u.zToken, strlen(def->u.zToken)); + } } return (int)(p - base); } @@ -1781,3 +1835,17 @@ tarantoolSqlGetMaxId(uint32_t space_id, uint32_t index_id, uint32_t fieldno, return tuple_field_u64(tuple, fieldno, max_id); } + +struct Expr* +space_column_default_expr(uint32_t space_id, uint32_t fieldno) +{ + struct space *space; + space = space_cache_find(space_id); + assert(space != NULL); + assert(space->def != NULL); + if (space->def->opts.is_view) + return NULL; + assert(space->def->field_count > fieldno); + + return space->def->fields[fieldno].default_value_expr; +} diff --git a/src/box/sql.h b/src/box/sql.h index 8a7c420..9dc218a 100644 --- a/src/box/sql.h +++ b/src/box/sql.h @@ -31,6 +31,9 @@ * SUCH DAMAGE. */ +#include +#include + #if defined(__cplusplus) extern "C" { #endif @@ -39,9 +42,12 @@ void sql_init(); void +sql_load_schema(); + +void sql_free(); -/* +/** * struct sqlite3 * * sql_get(); * @@ -51,10 +57,98 @@ sql_free(); * don't do anything finicky like sqlite3_close. * Behind the scenes, this sqlite was rigged to use Tarantool * as a data source. + * @retval SQL handle. */ struct sqlite3 * sql_get(); +struct Expr; +struct Parse; +struct Select; + +/** + * Perform parsing of provided expression. This is done by + * surrounding the expression w/ 'SELECT ' prefix and perform + * convetional parsing. Then extract result expression value from + * stuct Select and return it. + * @param db SQL context handle. + * @param expr Expression to parse. + * @param[out] result Result: AST structure. + * @param[out] err Error string if any. + * + * @retval Error code if any. + */ +int +sql_expr_compile(struct sqlite3 *db, + const char *expr, + struct Expr **result, + char **err); + +/** + * Recursively free storage occupied by AST expr. + * @param db SQL handle. + * @param p Pointer to root node. + * @param extern_alloc If true, pretend skeleton nodes to be + * allocated w/ external allocator, so do nothing for them. + */ +void +sql_expr_extract_select(struct Parse *parser, struct Select *select); + +/** + * Given space_id and field number, return default value + * for the field. + * @param space_id Space ID. + * @param fieldno Field index. + * @retval Pointer to AST corresponding to default value. + * Can be NULL if no DEFAULT specified or it is a view. + */ +struct Expr* +space_column_default_expr(uint32_t space_id, uint32_t fieldno); + +/** + * Return the number of bytes required to create a duplicate of the + * expression passed as the first argument. The second argument is a + * mask containing EXPRDUP_XXX flags. + * + * The value returned includes space to create a copy of the Expr struct + * itself and the buffer referred to by Expr.u.zToken, if any. + * + * If the EXPRDUP_REDUCE flag is set, then the return value includes + * space to duplicate all Expr nodes in the tree formed by Expr.pLeft + * and Expr.pRight variables (but not for any structures pointed to or + * descended from the Expr.x.pList or Expr.x.pSelect variables). + * @param expr Root expression of AST. + * @param flags The only possible flag is REDUCED, 0 otherwise. + * @retval Size in bytes needed to duplicate AST and all private + * strings. + */ +int +sql_expr_sizeof(struct Expr *p, int flags); + +/** + * This function is similar to sqlite3ExprDup(), except that if pzBuffer + * is not NULL then *pzBuffer is assumed to point to a buffer large enough + * to store the copy of expression p, the copies of p->u.zToken + * (if applicable), and the copies of the p->pLeft and p->pRight expressions, + * if any. Before returning, *pzBuffer is set to the first byte past the + * portion of the buffer copied into by this function. + * @param db SQL handle. + * @param p Root of expression's AST. + * @param dupFlags EXPRDUP_REDUCE or 0. + * @param pzBuffer If not NULL, then buffer to store duplicate. + */ +struct Expr * +sql_expr_dup(struct sqlite3 *db, struct Expr *p, int flags, char **buffer); + +/** + * Free AST pointed by expr. + * @param db SQL handle. + * @param expr Root pointer of ASR + * @param extern_alloc True if skeleton was allocated externally. + */ +void +sql_expr_free(struct sqlite3 *db, struct Expr *expr, bool extern_alloc); + #if defined(__cplusplus) } /* extern "C" { */ #endif diff --git a/src/box/sql/build.c b/src/box/sql/build.c index 05a7cc9..edcdc31 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -285,7 +285,7 @@ freeIndex(sqlite3 * db, Index * p) #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif - sqlite3ExprDelete(db, p->pPartIdxWhere); + sql_expr_free(db, p->pPartIdxWhere, false); sqlite3ExprListDelete(db, p->aColExpr); sqlite3DbFree(db, p->zColAff); sqlite3_free(p->aiRowEst); @@ -365,7 +365,7 @@ sqlite3DeleteColumnNames(sqlite3 * db, Table * pTable) if ((pCol = pTable->aCol) != 0) { for (i = 0; i < pTable->nCol; i++, pCol++) { sqlite3DbFree(db, pCol->zName); - sqlite3ExprDelete(db, pCol->pDflt); + sql_expr_free(db, pCol->pDflt, false); sqlite3DbFree(db, pCol->zColl); } sqlite3DbFree(db, pTable->aCol); @@ -892,7 +892,7 @@ sqlite3AddDefaultValue(Parse * pParse, ExprSpan * pSpan) * is required by pragma table_info. */ Expr x; - sqlite3ExprDelete(db, pCol->pDflt); + sql_expr_free(db, pCol->pDflt, false); memset(&x, 0, sizeof(x)); x.op = TK_SPAN; x.u.zToken = sqlite3DbStrNDup(db, (char *)pSpan->zStart, @@ -904,7 +904,7 @@ sqlite3AddDefaultValue(Parse * pParse, ExprSpan * pSpan) sqlite3DbFree(db, x.u.zToken); } } - sqlite3ExprDelete(db, pSpan->pExpr); + sql_expr_free(db, pSpan->pExpr, false); } @@ -1018,9 +1018,7 @@ sqlite3AddCheckConstraint(Parse * pParse, /* Parsing context */ } } else #endif - { - sqlite3ExprDelete(pParse->db, pCheckExpr); - } + sql_expr_free(pParse->db, pCheckExpr, false); } /* @@ -3268,7 +3266,7 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */ exit_create_index: if (pIndex) freeIndex(db, pIndex); - sqlite3ExprDelete(db, pPIWhere); + sql_expr_free(db, pPIWhere, false); sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); sqlite3DbFree(db, zName); @@ -3734,7 +3732,7 @@ sqlite3SrcListDelete(sqlite3 * db, SrcList * pList) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); sqlite3SelectDelete(db, pItem->pSelect); - sqlite3ExprDelete(db, pItem->pOn); + sql_expr_free(db, pItem->pOn, false); sqlite3IdListDelete(db, pItem->pUsing); } sqlite3DbFree(db, pList); @@ -3790,7 +3788,7 @@ sqlite3SrcListAppendFromTerm(Parse * pParse, /* Parsing context */ append_from_error: assert(p == 0); - sqlite3ExprDelete(db, pOn); + sql_expr_free(db, pOn, false); sqlite3IdListDelete(db, pUsing); sqlite3SelectDelete(db, pSubquery); return 0; diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index 2e09d92..7d1d715 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -212,10 +212,10 @@ sqlite3LimitWhere(Parse * pParse, /* The parser context */ return pInClause; limit_where_cleanup: - sqlite3ExprDelete(pParse->db, pWhere); + sql_expr_free(pParse->db, pWhere); sqlite3ExprListDelete(pParse->db, pOrderBy); - sqlite3ExprDelete(pParse->db, pLimit); - sqlite3ExprDelete(pParse->db, pOffset); + sql_expr_free(pParse->db, pLimit); + sql_expr_free(pParse->db, pOffset); return 0; } #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ @@ -571,7 +571,7 @@ sqlite3DeleteFrom(Parse * pParse, /* The parser context */ delete_from_cleanup: sqlite3SrcListDelete(db, pTabList); - sqlite3ExprDelete(db, pWhere); + sql_expr_free(db, pWhere, false); sqlite3DbFree(db, aToOpen); return; } @@ -636,9 +636,9 @@ sqlite3DeleteByKey(Parse *pParse, char *zTab, const char **columns, return; error: - sqlite3ExprDelete(pParse->db, where); + sql_expr_free(pParse->db, where, false); for (int i = 0; i < nPairs; ++i) - sqlite3ExprDelete(pParse->db, values[i]); + sql_expr_free(pParse->db, values[i], false); } /* Make sure "isView" and other macros defined above are undefined. Otherwise diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 89dcb23..5ae0c9c 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -492,7 +492,7 @@ sqlite3ExprForVectorField(Parse * pParse, /* Parsing context */ * pLeft->iTable: First in an array of register holding result, or 0 * if the result is not yet computed. * - * sqlite3ExprDelete() specifically skips the recursive delete of + * sql_expr_free() specifically skips the recursive delete of * pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector * can be attached to pRight to cause this node to take ownership of * pVector. Typically there will be multiple TK_SELECT_COLUMN nodes @@ -935,8 +935,8 @@ sqlite3ExprAttachSubtrees(sqlite3 * db, { if (pRoot == 0) { assert(db->mallocFailed); - sqlite3ExprDelete(db, pLeft); - sqlite3ExprDelete(db, pRight); + sql_expr_free(db, pLeft, false); + sql_expr_free(db, pRight, false); } else { if (pRight) { pRoot->pRight = pRight; @@ -1052,8 +1052,8 @@ sqlite3ExprAnd(sqlite3 * db, Expr * pLeft, Expr * pRight) } else if (pRight == 0) { return pLeft; } else if (exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight)) { - sqlite3ExprDelete(db, pLeft); - sqlite3ExprDelete(db, pRight); + sql_expr_free(db, pLeft, false); + sql_expr_free(db, pRight, false); return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); } else { @@ -1172,7 +1172,7 @@ sqlite3ExprAssignVarNumber(Parse * pParse, Expr * pExpr, u32 n) * Recursively delete an expression tree. */ static SQLITE_NOINLINE void -sqlite3ExprDeleteNN(sqlite3 * db, Expr * p) +sqlite3ExprDeleteNN(sqlite3 * db, Expr * p, bool extern_alloc) { assert(p != 0); /* Sanity check: Assert that the IntValue is non-negative if it exists */ @@ -1187,9 +1187,10 @@ sqlite3ExprDeleteNN(sqlite3 * db, Expr * p) if (!ExprHasProperty(p, (EP_TokenOnly | EP_Leaf))) { /* The Expr.x union is never used at the same time as Expr.pRight */ assert(p->x.pList == 0 || p->pRight == 0); - if (p->pLeft && p->op != TK_SELECT_COLUMN) - sqlite3ExprDeleteNN(db, p->pLeft); - sqlite3ExprDelete(db, p->pRight); + if (p->pLeft && p->op != TK_SELECT_COLUMN && !extern_alloc) + sqlite3ExprDeleteNN(db, p->pLeft, extern_alloc); + if (!extern_alloc) + sql_expr_free(db, p->pRight, extern_alloc); if (ExprHasProperty(p, EP_xIsSelect)) { sqlite3SelectDelete(db, p->x.pSelect); } else { @@ -1204,10 +1205,10 @@ sqlite3ExprDeleteNN(sqlite3 * db, Expr * p) } void -sqlite3ExprDelete(sqlite3 * db, Expr * p) +sql_expr_free(sqlite3 *db, Expr *expr, bool extern_alloc) { - if (p) - sqlite3ExprDeleteNN(db, p); + if (expr != NULL) + sqlite3ExprDeleteNN(db, expr, extern_alloc); } /* @@ -1298,61 +1299,39 @@ dupedExprNodeSize(Expr * p, int flags) return ROUND8(nByte); } -/* - * Return the number of bytes required to create a duplicate of the - * expression passed as the first argument. The second argument is a - * mask containing EXPRDUP_XXX flags. - * - * The value returned includes space to create a copy of the Expr struct - * itself and the buffer referred to by Expr.u.zToken, if any. - * - * If the EXPRDUP_REDUCE flag is set, then the return value includes - * space to duplicate all Expr nodes in the tree formed by Expr.pLeft - * and Expr.pRight variables (but not for any structures pointed to or - * descended from the Expr.x.pList or Expr.x.pSelect variables). - */ -static int -dupedExprSize(Expr * p, int flags) +int +sql_expr_sizeof(struct Expr *p, int flags) { - int nByte = 0; - if (p) { - nByte = dupedExprNodeSize(p, flags); + int size = 0; + if (p != NULL) { + size = dupedExprNodeSize(p, flags); if (flags & EXPRDUP_REDUCE) { - nByte += - dupedExprSize(p->pLeft, - flags) + dupedExprSize(p->pRight, - flags); + size += + sql_expr_sizeof(p->pLeft, flags) + + sql_expr_sizeof(p->pRight, flags); } } - return nByte; + return size; } -/* - * This function is similar to sqlite3ExprDup(), except that if pzBuffer - * is not NULL then *pzBuffer is assumed to point to a buffer large enough - * to store the copy of expression p, the copies of p->u.zToken - * (if applicable), and the copies of the p->pLeft and p->pRight expressions, - * if any. Before returning, *pzBuffer is set to the first byte past the - * portion of the buffer copied into by this function. - */ -static Expr * -exprDup(sqlite3 * db, Expr * p, int dupFlags, u8 ** pzBuffer) +struct Expr * +sql_expr_dup(struct sqlite3 *db, struct Expr *p, int flags, char **buffer) { Expr *pNew; /* Value to return */ - u8 *zAlloc; /* Memory space from which to build Expr object */ - u32 staticFlag; /* EP_Static if space not obtained from malloc */ + u32 staticFlag; /* EP_Static if space not obtained from malloc */ + char *zAlloc; /* Memory space from which to build Expr object */ assert(db != 0); assert(p); - assert(dupFlags == 0 || dupFlags == EXPRDUP_REDUCE); - assert(pzBuffer == 0 || dupFlags == EXPRDUP_REDUCE); + assert(flags == 0 || flags == EXPRDUP_REDUCE); /* Figure out where to write the new Expr structure. */ - if (pzBuffer) { - zAlloc = *pzBuffer; + if (buffer) { + zAlloc = *buffer; staticFlag = EP_Static; } else { - zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); + zAlloc = sqlite3DbMallocRawNN(db, + sql_expr_sizeof(p, flags)); staticFlag = 0; } pNew = (Expr *) zAlloc; @@ -1363,15 +1342,14 @@ exprDup(sqlite3 * db, Expr * p, int dupFlags, u8 ** pzBuffer) * EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed * by the copy of the p->u.zToken string (if any). */ - const unsigned nStructSize = dupedExprStructSize(p, dupFlags); + const unsigned nStructSize = dupedExprStructSize(p, flags); const int nNewSize = nStructSize & 0xfff; int nToken; - if (!ExprHasProperty(p, EP_IntValue) && p->u.zToken) { + if (!ExprHasProperty(p, EP_IntValue) && p->u.zToken) nToken = sqlite3Strlen30(p->u.zToken) + 1; - } else { + else nToken = 0; - } - if (dupFlags) { + if (flags) { assert(ExprHasProperty(p, EP_Reduced) == 0); memcpy(zAlloc, p, nNewSize); } else { @@ -1401,29 +1379,28 @@ exprDup(sqlite3 * db, Expr * p, int dupFlags, u8 ** pzBuffer) if (ExprHasProperty(p, EP_xIsSelect)) { pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, - dupFlags); + flags); } else { pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, - dupFlags); + flags); } } /* Fill in pNew->pLeft and pNew->pRight. */ if (ExprHasProperty(pNew, EP_Reduced | EP_TokenOnly)) { - zAlloc += dupedExprNodeSize(p, dupFlags); + zAlloc += dupedExprNodeSize(p, flags); if (!ExprHasProperty(pNew, EP_TokenOnly | EP_Leaf)) { pNew->pLeft = p->pLeft ? - exprDup(db, p->pLeft, EXPRDUP_REDUCE, - &zAlloc) : 0; + sql_expr_dup(db, p->pLeft, EXPRDUP_REDUCE, + &zAlloc) : 0; pNew->pRight = - p->pRight ? exprDup(db, p->pRight, - EXPRDUP_REDUCE, - &zAlloc) : 0; - } - if (pzBuffer) { - *pzBuffer = zAlloc; + p->pRight ? sql_expr_dup(db, p->pRight, + EXPRDUP_REDUCE, + &zAlloc) : 0; } + if (buffer) + *buffer = zAlloc; } else { if (!ExprHasProperty(p, EP_TokenOnly | EP_Leaf)) { if (pNew->op == TK_SELECT_COLUMN) { @@ -1496,7 +1473,7 @@ Expr * sqlite3ExprDup(sqlite3 * db, Expr * p, int flags) { assert(flags == 0 || flags == EXPRDUP_REDUCE); - return p ? exprDup(db, p, flags, 0) : 0; + return p ? sql_expr_dup(db, p, flags, 0) : 0; } ExprList * @@ -1726,7 +1703,7 @@ sqlite3ExprListAppend(Parse * pParse, /* Parsing context */ no_mem: /* Avoid leaking memory if malloc has failed. */ - sqlite3ExprDelete(db, pExpr); + sql_expr_free(db, pExpr, false); sqlite3ExprListDelete(db, pList); return 0; } @@ -1802,7 +1779,7 @@ sqlite3ExprListAppendVector(Parse * pParse, /* Parsing context */ } vector_append_error: - sqlite3ExprDelete(db, pExpr); + sql_expr_free(db, pExpr, false); sqlite3IdListDelete(db, pColumns); return pList; } @@ -1908,7 +1885,7 @@ exprListDeleteNN(sqlite3 * db, ExprList * pList) struct ExprList_item *pItem; assert(pList->a != 0 || pList->nExpr == 0); for (pItem = pList->a, i = 0; i < pList->nExpr; i++, pItem++) { - sqlite3ExprDelete(db, pItem->pExpr); + sql_expr_free(db, pItem->pExpr, false); sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zSpan); } @@ -2991,7 +2968,7 @@ sqlite3CodeSubselect(Parse * pParse, /* Parsing context */ dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } - sqlite3ExprDelete(pParse->db, pSel->pLimit); + sql_expr_free(pParse->db, pSel->pLimit, false); pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &sqlite3IntTokens[1], 0); @@ -4597,7 +4574,7 @@ sqlite3ExprCodeCopy(Parse * pParse, Expr * pExpr, int target) pExpr = sqlite3ExprDup(db, pExpr, 0); if (!db->mallocFailed) sqlite3ExprCode(pParse, pExpr, target); - sqlite3ExprDelete(db, pExpr); + sql_expr_free(db, pExpr, false); } /* @@ -5157,7 +5134,7 @@ sqlite3ExprIfFalseDup(Parse * pParse, Expr * pExpr, int dest, int jumpIfNull) if (db->mallocFailed == 0) { sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull); } - sqlite3ExprDelete(db, pCopy); + sql_expr_free(db, pCopy, false); } /* diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c index 9286f4c..aedfe94 100644 --- a/src/box/sql/fkey.c +++ b/src/box/sql/fkey.c @@ -698,10 +698,9 @@ fkScanChildren(Parse * pParse, /* Parse context */ } /* Clean up the WHERE clause constructed above. */ - sqlite3ExprDelete(db, pWhere); - if (iFkIfZero) { + sql_expr_free(db, pWhere, false); + if (iFkIfZero) sqlite3VdbeJumpHere(v, iFkIfZero); - } } /* @@ -737,10 +736,10 @@ fkTriggerDelete(sqlite3 * dbMem, Trigger * p) { if (p) { TriggerStep *pStep = p->step_list; - sqlite3ExprDelete(dbMem, pStep->pWhere); + sql_expr_free(dbMem, pStep->pWhere, false); sqlite3ExprListDelete(dbMem, pStep->pExprList); sqlite3SelectDelete(dbMem, pStep->pSelect); - sqlite3ExprDelete(dbMem, p->pWhen); + sql_expr_free(dbMem, p->pWhen, false); sqlite3DbFree(dbMem, p); } } @@ -1424,8 +1423,8 @@ fkActionTrigger(Parse * pParse, /* Parse context */ /* Re-enable the lookaside buffer, if it was disabled earlier. */ db->lookaside.bDisable--; - sqlite3ExprDelete(db, pWhere); - sqlite3ExprDelete(db, pWhen); + sql_expr_free(db, pWhere, false); + sql_expr_free(db, pWhen, false); sqlite3ExprListDelete(db, pList); sqlite3SelectDelete(db, pSelect); if (db->mallocFailed == 1) { diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index 42254dd..5336e89 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -33,8 +33,9 @@ * This file contains C code routines that are called by the parser * to handle INSERT statements in SQLite. */ -#include "sqliteInt.h" #include "box/session.h" +#include "sqliteInt.h" +#include "tarantoolInt.h" /* * Generate code that will open pTab as cursor iCur. @@ -340,6 +341,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */ int regTupleid; /* registers holding insert tupleid */ int regData; /* register holding first column to insert */ int *aRegIdx = 0; /* One register allocated to each index */ + uint32_t space_id = 0; #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ @@ -376,6 +378,8 @@ sqlite3Insert(Parse * pParse, /* Parser context */ goto insert_cleanup; } + space_id = SQLITE_PAGENO_TO_SPACEID(pTab->tnum); + /* Figure out if we have any triggers and if the table being * inserted into is a view */ @@ -671,13 +675,18 @@ sqlite3Insert(Parse * pParse, /* Parser context */ } if ((!useTempTable && !pList) || (pColumn && j >= pColumn->nId)) { - if (i == pTab->iAutoIncPKey) + if (i == pTab->iAutoIncPKey) { sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols + i + 1); - else + } else { + struct Expr *dflt = NULL; + dflt = space_column_default_expr( + space_id, + i); sqlite3ExprCode(pParse, - pTab->aCol[i].pDflt, + dflt, regCols + i + 1); + } } else if (useTempTable) { sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols + i + 1); @@ -748,8 +757,12 @@ sqlite3Insert(Parse * pParse, /* Parser context */ iRegStore); continue; } + struct Expr *dflt = NULL; + dflt = space_column_default_expr( + space_id, + i); sqlite3ExprCodeFactorable(pParse, - pTab->aCol[i].pDflt, + dflt, iRegStore); } else if (useTempTable) { if ((pTab->tabFlags & TF_Autoincrement) @@ -1106,10 +1119,13 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ } else if (onError == ON_CONFLICT_ACTION_DEFAULT) { onError = ON_CONFLICT_ACTION_ABORT; } - if (onError == ON_CONFLICT_ACTION_REPLACE - && pTab->aCol[i].pDflt == 0) { + struct Expr *dflt = NULL; + dflt = space_column_default_expr( + SQLITE_PAGENO_TO_SPACEID(pTab->tnum), + i); + if (onError == ON_CONFLICT_ACTION_REPLACE && dflt == 0) onError = ON_CONFLICT_ACTION_ABORT; - } + assert(onError == ON_CONFLICT_ACTION_ROLLBACK || onError == ON_CONFLICT_ACTION_ABORT || onError == ON_CONFLICT_ACTION_FAIL @@ -1145,7 +1161,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ sqlite3VdbeAddOp1(v, OP_NotNull, regNewData + 1 + i); VdbeCoverage(v); - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, + sqlite3ExprCode(pParse, dflt, regNewData + 1 + i); sqlite3VdbeJumpHere(v, addr1); break; diff --git a/src/box/sql/main.c b/src/box/sql/main.c index 1881e93..b77348c 100644 --- a/src/box/sql/main.c +++ b/src/box/sql/main.c @@ -2058,21 +2058,6 @@ sql_init_db(sqlite3 **out_db) setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); - if (rc == SQLITE_OK) { - struct session *user_session = current_session(); - int commit_internal = !(user_session->sql_flags - & SQLITE_InternChanges); - - assert(db->init.busy == 0); - db->init.busy = 1; - db->pSchema = sqlite3SchemaCreate(db); - rc = sqlite3InitDatabase(db); - if (rc != SQLITE_OK) - sqlite3SchemaClear(db); - db->init.busy = 0; - if (rc == SQLITE_OK && commit_internal) - sqlite3CommitInternalChanges(); - } opendb_out: rc = sqlite3_errcode(db); assert(db != 0 || rc == SQLITE_NOMEM); diff --git a/src/box/sql/parse.c b/src/box/sql/parse.c index 17ce309..9f547d2 100644 --- a/src/box/sql/parse.c +++ b/src/box/sql/parse.c @@ -81,7 +81,7 @@ static void disableLookaside(Parse *pParse){ pParse->db->lookaside.bDisable++; } -#line 392 "parse.y" +#line 398 "parse.y" /* ** For a compound SELECT statement, make sure p->pPrior->pNext==p for @@ -104,7 +104,7 @@ static void disableLookaside(Parse *pParse){ } } } -#line 831 "parse.y" +#line 837 "parse.y" /* This is a utility routine used to set the ExprSpan.zStart and ** ExprSpan.zEnd values of pOut so that the span covers the complete @@ -140,7 +140,7 @@ static void disableLookaside(Parse *pParse){ pOut->zStart = t.z; pOut->zEnd = &t.z[t.n]; } -#line 939 "parse.y" +#line 945 "parse.y" /* This routine constructs a binary expression node out of two ExprSpan ** objects and uses the result to populate a new ExprSpan object. @@ -163,7 +163,7 @@ static void disableLookaside(Parse *pParse){ pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0); } } -#line 1013 "parse.y" +#line 1019 "parse.y" /* Construct an expression node for a unary postfix operator */ @@ -176,7 +176,7 @@ static void disableLookaside(Parse *pParse){ pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); pOperand->zEnd = &pPostOp->z[pPostOp->n]; } -#line 1030 "parse.y" +#line 1036 "parse.y" /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ @@ -184,11 +184,11 @@ static void disableLookaside(Parse *pParse){ sqlite3 *db = pParse->db; if( pA && pY && pY->op==TK_NULL ){ pA->op = (u8)op; - sqlite3ExprDelete(db, pA->pRight); + sql_expr_free(db, pA->pRight, false); pA->pRight = 0; } } -#line 1058 "parse.y" +#line 1064 "parse.y" /* Construct an expression node for a unary prefix operator */ @@ -203,7 +203,7 @@ static void disableLookaside(Parse *pParse){ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); pOut->zEnd = pOperand->zEnd; } -#line 1263 "parse.y" +#line 1269 "parse.y" /* Add a single new term to an ExprList that is used to store a ** list of identifiers. Report an error if the ID list contains @@ -1468,7 +1468,7 @@ static void yy_destructor( case 183: /* oneselect */ case 194: /* values */ { -#line 386 "parse.y" +#line 392 "parse.y" sqlite3SelectDelete(pParse->db, (yypminor->yy279)); #line 1474 "parse.c" } @@ -1476,8 +1476,8 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy279)); case 160: /* term */ case 161: /* expr */ { -#line 829 "parse.y" -sqlite3ExprDelete(pParse->db, (yypminor->yy162).pExpr); +#line 835 "parse.y" +sql_expr_free(pParse->db, (yypminor->yy162).pExpr, false); #line 1482 "parse.c" } break; @@ -1494,7 +1494,7 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy162).pExpr); case 213: /* paren_exprlist */ case 215: /* case_exprlist */ { -#line 1261 "parse.y" +#line 1267 "parse.y" sqlite3ExprListDelete(pParse->db, (yypminor->yy382)); #line 1500 "parse.c" } @@ -1504,7 +1504,7 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy382)); case 199: /* seltablist */ case 200: /* stl_prefix */ { -#line 613 "parse.y" +#line 619 "parse.y" sqlite3SrcListDelete(pParse->db, (yypminor->yy387)); #line 1510 "parse.c" } @@ -1512,7 +1512,7 @@ sqlite3SrcListDelete(pParse->db, (yypminor->yy387)); case 184: /* with */ case 229: /* wqlist */ { -#line 1511 "parse.y" +#line 1517 "parse.y" sqlite3WithDelete(pParse->db, (yypminor->yy151)); #line 1518 "parse.c" } @@ -1524,8 +1524,8 @@ sqlite3WithDelete(pParse->db, (yypminor->yy151)); case 216: /* case_else */ case 225: /* when_clause */ { -#line 738 "parse.y" -sqlite3ExprDelete(pParse->db, (yypminor->yy362)); +#line 744 "parse.y" +sql_expr_free(pParse->db, (yypminor->yy362), false); #line 1530 "parse.c" } break; @@ -1533,7 +1533,7 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy362)); case 206: /* idlist */ case 209: /* idlist_opt */ { -#line 650 "parse.y" +#line 656 "parse.y" sqlite3IdListDelete(pParse->db, (yypminor->yy40)); #line 1539 "parse.c" } @@ -1541,14 +1541,14 @@ sqlite3IdListDelete(pParse->db, (yypminor->yy40)); case 221: /* trigger_cmd_list */ case 226: /* trigger_cmd */ { -#line 1385 "parse.y" +#line 1391 "parse.y" sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427)); #line 1547 "parse.c" } break; case 223: /* trigger_event */ { -#line 1371 "parse.y" +#line 1377 "parse.y" sqlite3IdListDelete(pParse->db, (yypminor->yy10).b); #line 1554 "parse.c" } @@ -2164,84 +2164,87 @@ static void yy_reduce( YYMINORTYPE yylhsminor; case 0: /* ecmd ::= explain cmdx SEMI */ #line 111 "parse.y" -{ sqlite3FinishCoding(pParse); } -#line 2169 "parse.c" +{ + if (!pParse->parse_only) + sqlite3FinishCoding(pParse); +} +#line 2172 "parse.c" break; case 1: /* ecmd ::= SEMI */ -#line 112 "parse.y" +#line 115 "parse.y" { sqlite3ErrorMsg(pParse, "syntax error: empty request"); } -#line 2176 "parse.c" +#line 2179 "parse.c" break; case 2: /* explain ::= EXPLAIN */ -#line 117 "parse.y" +#line 120 "parse.y" { pParse->explain = 1; } -#line 2181 "parse.c" +#line 2184 "parse.c" break; case 3: /* explain ::= EXPLAIN QUERY PLAN */ -#line 118 "parse.y" +#line 121 "parse.y" { pParse->explain = 2; } -#line 2186 "parse.c" +#line 2189 "parse.c" break; case 4: /* cmd ::= BEGIN transtype trans_opt */ -#line 150 "parse.y" +#line 153 "parse.y" {sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy52);} -#line 2191 "parse.c" +#line 2194 "parse.c" break; case 5: /* transtype ::= */ -#line 155 "parse.y" +#line 158 "parse.y" {yymsp[1].minor.yy52 = TK_DEFERRED;} -#line 2196 "parse.c" +#line 2199 "parse.c" break; case 6: /* transtype ::= DEFERRED */ -#line 156 "parse.y" +#line 159 "parse.y" {yymsp[0].minor.yy52 = yymsp[0].major; /*A-overwrites-X*/} -#line 2201 "parse.c" +#line 2204 "parse.c" break; case 7: /* cmd ::= COMMIT trans_opt */ case 8: /* cmd ::= END trans_opt */ yytestcase(yyruleno==8); -#line 157 "parse.y" +#line 160 "parse.y" {sqlite3CommitTransaction(pParse);} -#line 2207 "parse.c" +#line 2210 "parse.c" break; case 9: /* cmd ::= ROLLBACK trans_opt */ -#line 159 "parse.y" +#line 162 "parse.y" {sqlite3RollbackTransaction(pParse);} -#line 2212 "parse.c" +#line 2215 "parse.c" break; case 10: /* cmd ::= SAVEPOINT nm */ -#line 163 "parse.y" +#line 166 "parse.y" { sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); } -#line 2219 "parse.c" +#line 2222 "parse.c" break; case 11: /* cmd ::= RELEASE savepoint_opt nm */ -#line 166 "parse.y" +#line 169 "parse.y" { sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); } -#line 2226 "parse.c" +#line 2229 "parse.c" break; case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ -#line 169 "parse.y" +#line 172 "parse.y" { sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); } -#line 2233 "parse.c" +#line 2236 "parse.c" break; case 13: /* create_table ::= createkw TABLE ifnotexists nm */ -#line 176 "parse.y" +#line 179 "parse.y" { sqlite3StartTable(pParse,&yymsp[0].minor.yy0,yymsp[-1].minor.yy52); } -#line 2240 "parse.c" +#line 2243 "parse.c" break; case 14: /* createkw ::= CREATE */ -#line 179 "parse.y" +#line 182 "parse.y" {disableLookaside(pParse);} -#line 2245 "parse.c" +#line 2248 "parse.c" break; case 15: /* ifnotexists ::= */ case 38: /* autoinc ::= */ yytestcase(yyruleno==38); @@ -2250,89 +2253,89 @@ static void yy_reduce( case 72: /* ifexists ::= */ yytestcase(yyruleno==72); case 86: /* distinct ::= */ yytestcase(yyruleno==86); case 208: /* collate ::= */ yytestcase(yyruleno==208); -#line 182 "parse.y" +#line 185 "parse.y" {yymsp[1].minor.yy52 = 0;} -#line 2256 "parse.c" +#line 2259 "parse.c" break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -#line 183 "parse.y" +#line 186 "parse.y" {yymsp[-2].minor.yy52 = 1;} -#line 2261 "parse.c" +#line 2264 "parse.c" break; case 17: /* create_table_args ::= LP columnlist conslist_opt RP */ -#line 185 "parse.y" +#line 188 "parse.y" { sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0); } -#line 2268 "parse.c" +#line 2271 "parse.c" break; case 18: /* create_table_args ::= AS select */ -#line 188 "parse.y" +#line 191 "parse.y" { sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy279); sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy279); } -#line 2276 "parse.c" +#line 2279 "parse.c" break; case 19: /* columnname ::= nm typetoken */ -#line 194 "parse.y" +#line 197 "parse.y" {sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} -#line 2281 "parse.c" +#line 2284 "parse.c" break; case 20: /* nm ::= ID|INDEXED */ -#line 225 "parse.y" +#line 228 "parse.y" { if(yymsp[0].minor.yy0.isReserved) { sqlite3ErrorMsg(pParse, "keyword \"%T\" is reserved", &yymsp[0].minor.yy0); } } -#line 2290 "parse.c" +#line 2293 "parse.c" break; case 21: /* typetoken ::= */ case 56: /* conslist_opt ::= */ yytestcase(yyruleno==56); case 92: /* as ::= */ yytestcase(yyruleno==92); -#line 236 "parse.y" +#line 239 "parse.y" {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} -#line 2297 "parse.c" +#line 2300 "parse.c" break; case 22: /* typetoken ::= typename LP signed RP */ -#line 238 "parse.y" +#line 241 "parse.y" { yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); } -#line 2304 "parse.c" +#line 2307 "parse.c" break; case 23: /* typetoken ::= typename LP signed COMMA signed RP */ -#line 241 "parse.y" +#line 244 "parse.y" { yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); } -#line 2311 "parse.c" +#line 2314 "parse.c" break; case 24: /* typename ::= typename ID|STRING */ -#line 246 "parse.y" +#line 249 "parse.y" {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} -#line 2316 "parse.c" +#line 2319 "parse.c" break; case 25: /* ccons ::= CONSTRAINT nm */ case 58: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==58); -#line 255 "parse.y" +#line 258 "parse.y" {pParse->constraintName = yymsp[0].minor.yy0;} -#line 2322 "parse.c" +#line 2325 "parse.c" break; case 26: /* ccons ::= DEFAULT term */ case 28: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==28); -#line 256 "parse.y" +#line 259 "parse.y" {sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy162);} -#line 2328 "parse.c" +#line 2331 "parse.c" break; case 27: /* ccons ::= DEFAULT LP expr RP */ -#line 257 "parse.y" +#line 260 "parse.y" {sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy162);} -#line 2333 "parse.c" +#line 2336 "parse.c" break; case 29: /* ccons ::= DEFAULT MINUS term */ -#line 259 "parse.y" +#line 262 "parse.y" { ExprSpan v; v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy162.pExpr, 0); @@ -2340,222 +2343,225 @@ static void yy_reduce( v.zEnd = yymsp[0].minor.yy162.zEnd; sqlite3AddDefaultValue(pParse,&v); } -#line 2344 "parse.c" +#line 2347 "parse.c" break; case 30: /* ccons ::= DEFAULT ID|INDEXED */ -#line 266 "parse.y" +#line 269 "parse.y" { ExprSpan v; spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0); sqlite3AddDefaultValue(pParse,&v); } -#line 2353 "parse.c" +#line 2356 "parse.c" break; case 31: /* ccons ::= NOT NULL onconf */ -#line 276 "parse.y" +#line 279 "parse.y" {sqlite3AddNotNull(pParse, yymsp[0].minor.yy52);} -#line 2358 "parse.c" +#line 2361 "parse.c" break; case 32: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -#line 278 "parse.y" +#line 281 "parse.y" {sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy52,yymsp[0].minor.yy52,yymsp[-2].minor.yy52);} -#line 2363 "parse.c" +#line 2366 "parse.c" break; case 33: /* ccons ::= UNIQUE onconf */ -#line 279 "parse.y" +#line 282 "parse.y" {sqlite3CreateIndex(pParse,0,0,0,yymsp[0].minor.yy52,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} -#line 2369 "parse.c" +#line 2372 "parse.c" break; case 34: /* ccons ::= CHECK LP expr RP */ -#line 281 "parse.y" +#line 284 "parse.y" {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy162.pExpr);} -#line 2374 "parse.c" +#line 2377 "parse.c" break; case 35: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -#line 283 "parse.y" +#line 286 "parse.y" {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy382,yymsp[0].minor.yy52);} -#line 2379 "parse.c" +#line 2382 "parse.c" break; case 36: /* ccons ::= defer_subclause */ -#line 284 "parse.y" +#line 287 "parse.y" {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy52);} -#line 2384 "parse.c" +#line 2387 "parse.c" break; case 37: /* ccons ::= COLLATE ID|INDEXED */ -#line 285 "parse.y" +#line 288 "parse.y" {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} -#line 2389 "parse.c" +#line 2392 "parse.c" break; case 39: /* autoinc ::= AUTOINCR */ -#line 290 "parse.y" +#line 293 "parse.y" {yymsp[0].minor.yy52 = 1;} -#line 2394 "parse.c" +#line 2397 "parse.c" break; case 40: /* refargs ::= */ -#line 298 "parse.y" +#line 301 "parse.y" { yymsp[1].minor.yy52 = ON_CONFLICT_ACTION_NONE*0x0101; /* EV: R-19803-45884 */} -#line 2399 "parse.c" +#line 2402 "parse.c" break; case 41: /* refargs ::= refargs refarg */ -#line 299 "parse.y" +#line 302 "parse.y" { yymsp[-1].minor.yy52 = (yymsp[-1].minor.yy52 & ~yymsp[0].minor.yy107.mask) | yymsp[0].minor.yy107.value; } -#line 2404 "parse.c" +#line 2407 "parse.c" break; case 42: /* refarg ::= MATCH nm */ -#line 301 "parse.y" +#line 304 "parse.y" { yymsp[-1].minor.yy107.value = 0; yymsp[-1].minor.yy107.mask = 0x000000; } -#line 2409 "parse.c" +#line 2412 "parse.c" break; case 43: /* refarg ::= ON INSERT refact */ -#line 302 "parse.y" +#line 305 "parse.y" { yymsp[-2].minor.yy107.value = 0; yymsp[-2].minor.yy107.mask = 0x000000; } -#line 2414 "parse.c" +#line 2417 "parse.c" break; case 44: /* refarg ::= ON DELETE refact */ -#line 303 "parse.y" +#line 306 "parse.y" { yymsp[-2].minor.yy107.value = yymsp[0].minor.yy52; yymsp[-2].minor.yy107.mask = 0x0000ff; } -#line 2419 "parse.c" +#line 2422 "parse.c" break; case 45: /* refarg ::= ON UPDATE refact */ -#line 304 "parse.y" +#line 307 "parse.y" { yymsp[-2].minor.yy107.value = yymsp[0].minor.yy52<<8; yymsp[-2].minor.yy107.mask = 0x00ff00; } -#line 2424 "parse.c" +#line 2427 "parse.c" break; case 46: /* refact ::= SET NULL */ -#line 306 "parse.y" +#line 309 "parse.y" { yymsp[-1].minor.yy52 = OE_SetNull; /* EV: R-33326-45252 */} -#line 2429 "parse.c" +#line 2432 "parse.c" break; case 47: /* refact ::= SET DEFAULT */ -#line 307 "parse.y" +#line 310 "parse.y" { yymsp[-1].minor.yy52 = OE_SetDflt; /* EV: R-33326-45252 */} -#line 2434 "parse.c" +#line 2437 "parse.c" break; case 48: /* refact ::= CASCADE */ -#line 308 "parse.y" +#line 311 "parse.y" { yymsp[0].minor.yy52 = OE_Cascade; /* EV: R-33326-45252 */} -#line 2439 "parse.c" +#line 2442 "parse.c" break; case 49: /* refact ::= RESTRICT */ -#line 309 "parse.y" +#line 312 "parse.y" { yymsp[0].minor.yy52 = OE_Restrict; /* EV: R-33326-45252 */} -#line 2444 "parse.c" +#line 2447 "parse.c" break; case 50: /* refact ::= NO ACTION */ -#line 310 "parse.y" +#line 313 "parse.y" { yymsp[-1].minor.yy52 = ON_CONFLICT_ACTION_NONE; /* EV: R-33326-45252 */} -#line 2449 "parse.c" +#line 2452 "parse.c" break; case 51: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -#line 312 "parse.y" +#line 315 "parse.y" {yymsp[-2].minor.yy52 = 0;} -#line 2454 "parse.c" +#line 2457 "parse.c" break; case 52: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 67: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==67); case 138: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==138); -#line 313 "parse.y" +#line 316 "parse.y" {yymsp[-1].minor.yy52 = yymsp[0].minor.yy52;} -#line 2461 "parse.c" +#line 2464 "parse.c" break; case 54: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 71: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==71); case 180: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==180); case 183: /* in_op ::= NOT IN */ yytestcase(yyruleno==183); case 209: /* collate ::= COLLATE ID|INDEXED */ yytestcase(yyruleno==209); -#line 316 "parse.y" +#line 319 "parse.y" {yymsp[-1].minor.yy52 = 1;} -#line 2470 "parse.c" +#line 2473 "parse.c" break; case 55: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -#line 317 "parse.y" +#line 320 "parse.y" {yymsp[-1].minor.yy52 = 0;} -#line 2475 "parse.c" +#line 2478 "parse.c" break; case 57: /* tconscomma ::= COMMA */ -#line 323 "parse.y" +#line 326 "parse.y" {pParse->constraintName.n = 0;} -#line 2480 "parse.c" +#line 2483 "parse.c" break; case 59: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -#line 327 "parse.y" +#line 330 "parse.y" {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy382,yymsp[0].minor.yy52,yymsp[-2].minor.yy52,0);} -#line 2485 "parse.c" +#line 2488 "parse.c" break; case 60: /* tcons ::= UNIQUE LP sortlist RP onconf */ -#line 329 "parse.y" +#line 332 "parse.y" {sqlite3CreateIndex(pParse,0,0,yymsp[-2].minor.yy382,yymsp[0].minor.yy52,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} -#line 2491 "parse.c" +#line 2494 "parse.c" break; case 61: /* tcons ::= CHECK LP expr RP onconf */ -#line 332 "parse.y" +#line 335 "parse.y" {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy162.pExpr);} -#line 2496 "parse.c" +#line 2499 "parse.c" break; case 62: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ -#line 334 "parse.y" +#line 337 "parse.y" { sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy382, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy382, yymsp[-1].minor.yy52); sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy52); } -#line 2504 "parse.c" +#line 2507 "parse.c" break; case 64: /* onconf ::= */ case 66: /* orconf ::= */ yytestcase(yyruleno==66); -#line 348 "parse.y" +#line 351 "parse.y" {yymsp[1].minor.yy52 = ON_CONFLICT_ACTION_DEFAULT;} -#line 2510 "parse.c" +#line 2513 "parse.c" break; case 65: /* onconf ::= ON CONFLICT resolvetype */ -#line 349 "parse.y" +#line 352 "parse.y" {yymsp[-2].minor.yy52 = yymsp[0].minor.yy52;} -#line 2515 "parse.c" +#line 2518 "parse.c" break; case 68: /* resolvetype ::= IGNORE */ -#line 353 "parse.y" +#line 356 "parse.y" {yymsp[0].minor.yy52 = ON_CONFLICT_ACTION_IGNORE;} -#line 2520 "parse.c" +#line 2523 "parse.c" break; case 69: /* resolvetype ::= REPLACE */ case 139: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==139); -#line 354 "parse.y" +#line 357 "parse.y" {yymsp[0].minor.yy52 = ON_CONFLICT_ACTION_REPLACE;} -#line 2526 "parse.c" +#line 2529 "parse.c" break; case 70: /* cmd ::= DROP TABLE ifexists fullname */ -#line 358 "parse.y" +#line 361 "parse.y" { sqlite3DropTable(pParse, yymsp[0].minor.yy387, 0, yymsp[-1].minor.yy52); } -#line 2533 "parse.c" +#line 2536 "parse.c" break; case 73: /* cmd ::= createkw VIEW ifnotexists nm eidlist_opt AS select */ -#line 369 "parse.y" +#line 372 "parse.y" { sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy382, yymsp[0].minor.yy279, yymsp[-4].minor.yy52); } -#line 2540 "parse.c" +#line 2543 "parse.c" break; case 74: /* cmd ::= DROP VIEW ifexists fullname */ -#line 372 "parse.y" +#line 375 "parse.y" { sqlite3DropTable(pParse, yymsp[0].minor.yy387, 1, yymsp[-1].minor.yy52); } -#line 2547 "parse.c" +#line 2550 "parse.c" break; case 75: /* cmd ::= select */ -#line 379 "parse.y" +#line 382 "parse.y" { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy279, &dest); + if(!pParse->parse_only) + sqlite3Select(pParse, yymsp[0].minor.yy279, &dest); + else + sql_expr_extract_select(pParse, yymsp[0].minor.yy279); sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy279); } -#line 2556 "parse.c" +#line 2562 "parse.c" break; case 76: /* select ::= with selectnowith */ -#line 416 "parse.y" +#line 422 "parse.y" { Select *p = yymsp[0].minor.yy279; if( p ){ @@ -2566,10 +2572,10 @@ static void yy_reduce( } yymsp[-1].minor.yy279 = p; /*A-overwrites-W*/ } -#line 2570 "parse.c" +#line 2576 "parse.c" break; case 77: /* selectnowith ::= selectnowith multiselect_op oneselect */ -#line 429 "parse.y" +#line 435 "parse.y" { Select *pRhs = yymsp[0].minor.yy279; Select *pLhs = yymsp[-2].minor.yy279; @@ -2592,21 +2598,21 @@ static void yy_reduce( } yymsp[-2].minor.yy279 = pRhs; } -#line 2596 "parse.c" +#line 2602 "parse.c" break; case 78: /* multiselect_op ::= UNION */ case 80: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==80); -#line 452 "parse.y" +#line 458 "parse.y" {yymsp[0].minor.yy52 = yymsp[0].major; /*A-overwrites-OP*/} -#line 2602 "parse.c" +#line 2608 "parse.c" break; case 79: /* multiselect_op ::= UNION ALL */ -#line 453 "parse.y" +#line 459 "parse.y" {yymsp[-1].minor.yy52 = TK_ALL;} -#line 2607 "parse.c" +#line 2613 "parse.c" break; case 81: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ -#line 457 "parse.y" +#line 463 "parse.y" { #ifdef SELECTTRACE_ENABLED Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/ @@ -2637,17 +2643,17 @@ static void yy_reduce( } #endif /* SELECTRACE_ENABLED */ } -#line 2641 "parse.c" +#line 2647 "parse.c" break; case 82: /* values ::= VALUES LP nexprlist RP */ -#line 491 "parse.y" +#line 497 "parse.y" { yymsp[-3].minor.yy279 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy382,0,0,0,0,0,SF_Values,0,0); } -#line 2648 "parse.c" +#line 2654 "parse.c" break; case 83: /* values ::= values COMMA LP exprlist RP */ -#line 494 "parse.y" +#line 500 "parse.y" { Select *pRight, *pLeft = yymsp[-4].minor.yy279; pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy382,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); @@ -2660,17 +2666,17 @@ static void yy_reduce( yymsp[-4].minor.yy279 = pLeft; } } -#line 2664 "parse.c" +#line 2670 "parse.c" break; case 84: /* distinct ::= DISTINCT */ -#line 511 "parse.y" +#line 517 "parse.y" {yymsp[0].minor.yy52 = SF_Distinct;} -#line 2669 "parse.c" +#line 2675 "parse.c" break; case 85: /* distinct ::= ALL */ -#line 512 "parse.y" +#line 518 "parse.y" {yymsp[0].minor.yy52 = SF_All;} -#line 2674 "parse.c" +#line 2680 "parse.c" break; case 87: /* sclp ::= */ case 113: /* orderby_opt ::= */ yytestcase(yyruleno==113); @@ -2678,94 +2684,94 @@ static void yy_reduce( case 196: /* exprlist ::= */ yytestcase(yyruleno==196); case 199: /* paren_exprlist ::= */ yytestcase(yyruleno==199); case 204: /* eidlist_opt ::= */ yytestcase(yyruleno==204); -#line 525 "parse.y" +#line 531 "parse.y" {yymsp[1].minor.yy382 = 0;} -#line 2684 "parse.c" +#line 2690 "parse.c" break; case 88: /* selcollist ::= sclp expr as */ -#line 526 "parse.y" +#line 532 "parse.y" { yymsp[-2].minor.yy382 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy382, yymsp[-1].minor.yy162.pExpr); if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy382, &yymsp[0].minor.yy0, 1); sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy382,&yymsp[-1].minor.yy162); } -#line 2693 "parse.c" +#line 2699 "parse.c" break; case 89: /* selcollist ::= sclp STAR */ -#line 531 "parse.y" +#line 537 "parse.y" { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); yymsp[-1].minor.yy382 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy382, p); } -#line 2701 "parse.c" +#line 2707 "parse.c" break; case 90: /* selcollist ::= sclp nm DOT STAR */ -#line 535 "parse.y" +#line 541 "parse.y" { Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); yymsp[-3].minor.yy382 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy382, pDot); } -#line 2711 "parse.c" +#line 2717 "parse.c" break; case 91: /* as ::= AS nm */ case 218: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==218); case 219: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==219); -#line 546 "parse.y" +#line 552 "parse.y" {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} -#line 2718 "parse.c" +#line 2724 "parse.c" break; case 93: /* from ::= */ -#line 560 "parse.y" +#line 566 "parse.y" {yymsp[1].minor.yy387 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy387));} -#line 2723 "parse.c" +#line 2729 "parse.c" break; case 94: /* from ::= FROM seltablist */ -#line 561 "parse.y" +#line 567 "parse.y" { yymsp[-1].minor.yy387 = yymsp[0].minor.yy387; sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy387); } -#line 2731 "parse.c" +#line 2737 "parse.c" break; case 95: /* stl_prefix ::= seltablist joinop */ -#line 569 "parse.y" +#line 575 "parse.y" { if( ALWAYS(yymsp[-1].minor.yy387 && yymsp[-1].minor.yy387->nSrc>0) ) yymsp[-1].minor.yy387->a[yymsp[-1].minor.yy387->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy52; } -#line 2738 "parse.c" +#line 2744 "parse.c" break; case 96: /* stl_prefix ::= */ -#line 572 "parse.y" +#line 578 "parse.y" {yymsp[1].minor.yy387 = 0;} -#line 2743 "parse.c" +#line 2749 "parse.c" break; case 97: /* seltablist ::= stl_prefix nm as indexed_opt on_opt using_opt */ -#line 574 "parse.y" +#line 580 "parse.y" { yymsp[-5].minor.yy387 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy387,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy362,yymsp[0].minor.yy40); sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy387, &yymsp[-2].minor.yy0); } -#line 2751 "parse.c" +#line 2757 "parse.c" break; case 98: /* seltablist ::= stl_prefix nm LP exprlist RP as on_opt using_opt */ -#line 579 "parse.y" +#line 585 "parse.y" { yymsp[-7].minor.yy387 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy387,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy362,yymsp[0].minor.yy40); sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy387, yymsp[-4].minor.yy382); } -#line 2759 "parse.c" +#line 2765 "parse.c" break; case 99: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ -#line 585 "parse.y" +#line 591 "parse.y" { yymsp[-6].minor.yy387 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy387,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy279,yymsp[-1].minor.yy362,yymsp[0].minor.yy40); } -#line 2766 "parse.c" +#line 2772 "parse.c" break; case 100: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ -#line 589 "parse.y" +#line 595 "parse.y" { if( yymsp[-6].minor.yy387==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy362==0 && yymsp[0].minor.yy40==0 ){ yymsp[-6].minor.yy387 = yymsp[-4].minor.yy387; @@ -2787,135 +2793,135 @@ static void yy_reduce( yymsp[-6].minor.yy387 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy387,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy362,yymsp[0].minor.yy40); } } -#line 2791 "parse.c" +#line 2797 "parse.c" break; case 101: /* fullname ::= nm */ -#line 615 "parse.y" +#line 621 "parse.y" {yymsp[0].minor.yy387 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} -#line 2796 "parse.c" +#line 2802 "parse.c" break; case 102: /* joinop ::= COMMA|JOIN */ -#line 621 "parse.y" +#line 627 "parse.y" { yymsp[0].minor.yy52 = JT_INNER; } -#line 2801 "parse.c" +#line 2807 "parse.c" break; case 103: /* joinop ::= JOIN_KW JOIN */ -#line 623 "parse.y" +#line 629 "parse.y" {yymsp[-1].minor.yy52 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} -#line 2806 "parse.c" +#line 2812 "parse.c" break; case 104: /* joinop ::= JOIN_KW join_nm JOIN */ -#line 625 "parse.y" +#line 631 "parse.y" {yymsp[-2].minor.yy52 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} -#line 2811 "parse.c" +#line 2817 "parse.c" break; case 105: /* joinop ::= JOIN_KW join_nm join_nm JOIN */ -#line 627 "parse.y" +#line 633 "parse.y" {yymsp[-3].minor.yy52 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} -#line 2816 "parse.c" +#line 2822 "parse.c" break; case 106: /* on_opt ::= ON expr */ case 123: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==123); case 130: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==130); case 192: /* case_else ::= ELSE expr */ yytestcase(yyruleno==192); -#line 631 "parse.y" +#line 637 "parse.y" {yymsp[-1].minor.yy362 = yymsp[0].minor.yy162.pExpr;} -#line 2824 "parse.c" +#line 2830 "parse.c" break; case 107: /* on_opt ::= */ case 122: /* having_opt ::= */ yytestcase(yyruleno==122); case 129: /* where_opt ::= */ yytestcase(yyruleno==129); case 193: /* case_else ::= */ yytestcase(yyruleno==193); case 195: /* case_operand ::= */ yytestcase(yyruleno==195); -#line 632 "parse.y" +#line 638 "parse.y" {yymsp[1].minor.yy362 = 0;} -#line 2833 "parse.c" +#line 2839 "parse.c" break; case 108: /* indexed_opt ::= */ -#line 645 "parse.y" +#line 651 "parse.y" {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} -#line 2838 "parse.c" +#line 2844 "parse.c" break; case 109: /* indexed_opt ::= INDEXED BY nm */ -#line 646 "parse.y" +#line 652 "parse.y" {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} -#line 2843 "parse.c" +#line 2849 "parse.c" break; case 110: /* indexed_opt ::= NOT INDEXED */ -#line 647 "parse.y" +#line 653 "parse.y" {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} -#line 2848 "parse.c" +#line 2854 "parse.c" break; case 111: /* using_opt ::= USING LP idlist RP */ -#line 651 "parse.y" +#line 657 "parse.y" {yymsp[-3].minor.yy40 = yymsp[-1].minor.yy40;} -#line 2853 "parse.c" +#line 2859 "parse.c" break; case 112: /* using_opt ::= */ case 140: /* idlist_opt ::= */ yytestcase(yyruleno==140); -#line 652 "parse.y" +#line 658 "parse.y" {yymsp[1].minor.yy40 = 0;} -#line 2859 "parse.c" +#line 2865 "parse.c" break; case 114: /* orderby_opt ::= ORDER BY sortlist */ case 121: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==121); -#line 666 "parse.y" +#line 672 "parse.y" {yymsp[-2].minor.yy382 = yymsp[0].minor.yy382;} -#line 2865 "parse.c" +#line 2871 "parse.c" break; case 115: /* sortlist ::= sortlist COMMA expr sortorder */ -#line 667 "parse.y" +#line 673 "parse.y" { yymsp[-3].minor.yy382 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy382,yymsp[-1].minor.yy162.pExpr); sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy382,yymsp[0].minor.yy52); } -#line 2873 "parse.c" +#line 2879 "parse.c" break; case 116: /* sortlist ::= expr sortorder */ -#line 671 "parse.y" +#line 677 "parse.y" { yymsp[-1].minor.yy382 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy162.pExpr); /*A-overwrites-Y*/ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy382,yymsp[0].minor.yy52); } -#line 2881 "parse.c" +#line 2887 "parse.c" break; case 117: /* sortorder ::= ASC */ -#line 678 "parse.y" +#line 684 "parse.y" {yymsp[0].minor.yy52 = SQLITE_SO_ASC;} -#line 2886 "parse.c" +#line 2892 "parse.c" break; case 118: /* sortorder ::= DESC */ -#line 679 "parse.y" +#line 685 "parse.y" {yymsp[0].minor.yy52 = SQLITE_SO_DESC;} -#line 2891 "parse.c" +#line 2897 "parse.c" break; case 119: /* sortorder ::= */ -#line 680 "parse.y" +#line 686 "parse.y" {yymsp[1].minor.yy52 = SQLITE_SO_UNDEFINED;} -#line 2896 "parse.c" +#line 2902 "parse.c" break; case 124: /* limit_opt ::= */ -#line 705 "parse.y" +#line 711 "parse.y" {yymsp[1].minor.yy384.pLimit = 0; yymsp[1].minor.yy384.pOffset = 0;} -#line 2901 "parse.c" +#line 2907 "parse.c" break; case 125: /* limit_opt ::= LIMIT expr */ -#line 706 "parse.y" +#line 712 "parse.y" {yymsp[-1].minor.yy384.pLimit = yymsp[0].minor.yy162.pExpr; yymsp[-1].minor.yy384.pOffset = 0;} -#line 2906 "parse.c" +#line 2912 "parse.c" break; case 126: /* limit_opt ::= LIMIT expr OFFSET expr */ -#line 708 "parse.y" +#line 714 "parse.y" {yymsp[-3].minor.yy384.pLimit = yymsp[-2].minor.yy162.pExpr; yymsp[-3].minor.yy384.pOffset = yymsp[0].minor.yy162.pExpr;} -#line 2911 "parse.c" +#line 2917 "parse.c" break; case 127: /* limit_opt ::= LIMIT expr COMMA expr */ -#line 710 "parse.y" +#line 716 "parse.y" {yymsp[-3].minor.yy384.pOffset = yymsp[-2].minor.yy162.pExpr; yymsp[-3].minor.yy384.pLimit = yymsp[0].minor.yy162.pExpr;} -#line 2916 "parse.c" +#line 2922 "parse.c" break; case 128: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */ -#line 727 "parse.y" +#line 733 "parse.y" { sqlite3WithPush(pParse, yymsp[-5].minor.yy151, 1); sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy387, &yymsp[-1].minor.yy0); @@ -2924,10 +2930,10 @@ static void yy_reduce( pParse->initiateTTrans = true; sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy387,yymsp[0].minor.yy362); } -#line 2928 "parse.c" +#line 2934 "parse.c" break; case 131: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */ -#line 760 "parse.y" +#line 766 "parse.y" { sqlite3WithPush(pParse, yymsp[-7].minor.yy151, 1); sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy387, &yymsp[-3].minor.yy0); @@ -2937,41 +2943,41 @@ static void yy_reduce( pParse->initiateTTrans = true; sqlite3Update(pParse,yymsp[-4].minor.yy387,yymsp[-1].minor.yy382,yymsp[0].minor.yy362,yymsp[-5].minor.yy52); } -#line 2941 "parse.c" +#line 2947 "parse.c" break; case 132: /* setlist ::= setlist COMMA nm EQ expr */ -#line 774 "parse.y" +#line 780 "parse.y" { yymsp[-4].minor.yy382 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy382, yymsp[0].minor.yy162.pExpr); sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy382, &yymsp[-2].minor.yy0, 1); } -#line 2949 "parse.c" +#line 2955 "parse.c" break; case 133: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ -#line 778 "parse.y" +#line 784 "parse.y" { yymsp[-6].minor.yy382 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy382, yymsp[-3].minor.yy40, yymsp[0].minor.yy162.pExpr); } -#line 2956 "parse.c" +#line 2962 "parse.c" break; case 134: /* setlist ::= nm EQ expr */ -#line 781 "parse.y" +#line 787 "parse.y" { yylhsminor.yy382 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy162.pExpr); sqlite3ExprListSetName(pParse, yylhsminor.yy382, &yymsp[-2].minor.yy0, 1); } -#line 2964 "parse.c" +#line 2970 "parse.c" yymsp[-2].minor.yy382 = yylhsminor.yy382; break; case 135: /* setlist ::= LP idlist RP EQ expr */ -#line 785 "parse.y" +#line 791 "parse.y" { yymsp[-4].minor.yy382 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy40, yymsp[0].minor.yy162.pExpr); } -#line 2972 "parse.c" +#line 2978 "parse.c" break; case 136: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */ -#line 791 "parse.y" +#line 797 "parse.y" { sqlite3WithPush(pParse, yymsp[-5].minor.yy151, 1); sqlSubProgramsRemaining = SQL_MAX_COMPILING_TRIGGERS; @@ -2979,10 +2985,10 @@ static void yy_reduce( pParse->initiateTTrans = true; sqlite3Insert(pParse, yymsp[-2].minor.yy387, yymsp[0].minor.yy279, yymsp[-1].minor.yy40, yymsp[-4].minor.yy52); } -#line 2983 "parse.c" +#line 2989 "parse.c" break; case 137: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */ -#line 799 "parse.y" +#line 805 "parse.y" { sqlite3WithPush(pParse, yymsp[-6].minor.yy151, 1); sqlSubProgramsRemaining = SQL_MAX_COMPILING_TRIGGERS; @@ -2990,64 +2996,64 @@ static void yy_reduce( pParse->initiateTTrans = true; sqlite3Insert(pParse, yymsp[-3].minor.yy387, 0, yymsp[-2].minor.yy40, yymsp[-5].minor.yy52); } -#line 2994 "parse.c" +#line 3000 "parse.c" break; case 141: /* idlist_opt ::= LP idlist RP */ -#line 817 "parse.y" +#line 823 "parse.y" {yymsp[-2].minor.yy40 = yymsp[-1].minor.yy40;} -#line 2999 "parse.c" +#line 3005 "parse.c" break; case 142: /* idlist ::= idlist COMMA nm */ -#line 819 "parse.y" +#line 825 "parse.y" {yymsp[-2].minor.yy40 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy40,&yymsp[0].minor.yy0);} -#line 3004 "parse.c" +#line 3010 "parse.c" break; case 143: /* idlist ::= nm */ -#line 821 "parse.y" +#line 827 "parse.y" {yymsp[0].minor.yy40 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} -#line 3009 "parse.c" +#line 3015 "parse.c" break; case 144: /* expr ::= LP expr RP */ -#line 870 "parse.y" +#line 876 "parse.y" {spanSet(&yymsp[-2].minor.yy162,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy162.pExpr = yymsp[-1].minor.yy162.pExpr;} -#line 3014 "parse.c" +#line 3020 "parse.c" break; case 145: /* term ::= NULL */ case 149: /* term ::= FLOAT|BLOB */ yytestcase(yyruleno==149); case 150: /* term ::= STRING */ yytestcase(yyruleno==150); -#line 871 "parse.y" +#line 877 "parse.y" {spanExpr(&yymsp[0].minor.yy162,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/} -#line 3021 "parse.c" +#line 3027 "parse.c" break; case 146: /* expr ::= ID|INDEXED */ case 147: /* expr ::= JOIN_KW */ yytestcase(yyruleno==147); -#line 872 "parse.y" +#line 878 "parse.y" {spanExpr(&yymsp[0].minor.yy162,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} -#line 3027 "parse.c" +#line 3033 "parse.c" break; case 148: /* expr ::= nm DOT nm */ -#line 874 "parse.y" +#line 880 "parse.y" { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); spanSet(&yymsp[-2].minor.yy162,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ yymsp[-2].minor.yy162.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } -#line 3037 "parse.c" +#line 3043 "parse.c" break; case 151: /* term ::= INTEGER */ -#line 882 "parse.y" +#line 888 "parse.y" { yylhsminor.yy162.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); yylhsminor.yy162.zStart = yymsp[0].minor.yy0.z; yylhsminor.yy162.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n; if( yylhsminor.yy162.pExpr ) yylhsminor.yy162.pExpr->flags |= EP_Leaf; } -#line 3047 "parse.c" +#line 3053 "parse.c" yymsp[0].minor.yy162 = yylhsminor.yy162; break; case 152: /* expr ::= VARIABLE */ -#line 888 "parse.y" +#line 894 "parse.y" { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; @@ -3069,27 +3075,27 @@ static void yy_reduce( } } } -#line 3073 "parse.c" +#line 3079 "parse.c" break; case 153: /* expr ::= expr COLLATE ID|INDEXED */ -#line 909 "parse.y" +#line 915 "parse.y" { yymsp[-2].minor.yy162.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy162.pExpr, &yymsp[0].minor.yy0, 1); yymsp[-2].minor.yy162.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } -#line 3081 "parse.c" +#line 3087 "parse.c" break; case 154: /* expr ::= CAST LP expr AS typetoken RP */ -#line 914 "parse.y" +#line 920 "parse.y" { spanSet(&yymsp[-5].minor.yy162,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ yymsp[-5].minor.yy162.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy162.pExpr, yymsp[-3].minor.yy162.pExpr, 0); } -#line 3090 "parse.c" +#line 3096 "parse.c" break; case 155: /* expr ::= ID|INDEXED LP distinct exprlist RP */ -#line 920 "parse.y" +#line 926 "parse.y" { if( yymsp[-1].minor.yy382 && yymsp[-1].minor.yy382->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); @@ -3100,29 +3106,29 @@ static void yy_reduce( yylhsminor.yy162.pExpr->flags |= EP_Distinct; } } -#line 3104 "parse.c" +#line 3110 "parse.c" yymsp[-4].minor.yy162 = yylhsminor.yy162; break; case 156: /* expr ::= ID|INDEXED LP STAR RP */ -#line 930 "parse.y" +#line 936 "parse.y" { yylhsminor.yy162.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); spanSet(&yylhsminor.yy162,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 3113 "parse.c" +#line 3119 "parse.c" yymsp[-3].minor.yy162 = yylhsminor.yy162; break; case 157: /* term ::= CTIME_KW */ -#line 934 "parse.y" +#line 940 "parse.y" { yylhsminor.yy162.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0); spanSet(&yylhsminor.yy162, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } -#line 3122 "parse.c" +#line 3128 "parse.c" yymsp[0].minor.yy162 = yylhsminor.yy162; break; case 158: /* expr ::= LP nexprlist COMMA expr RP */ -#line 963 "parse.y" +#line 969 "parse.y" { ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy382, yymsp[-1].minor.yy162.pExpr); yylhsminor.yy162.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); @@ -3133,7 +3139,7 @@ static void yy_reduce( sqlite3ExprListDelete(pParse->db, pList); } } -#line 3137 "parse.c" +#line 3143 "parse.c" yymsp[-4].minor.yy162 = yylhsminor.yy162; break; case 159: /* expr ::= expr AND expr */ @@ -3144,22 +3150,22 @@ static void yy_reduce( case 164: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==164); case 165: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==165); case 166: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==166); -#line 974 "parse.y" +#line 980 "parse.y" {spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy162,&yymsp[0].minor.yy162);} -#line 3150 "parse.c" +#line 3156 "parse.c" break; case 167: /* likeop ::= LIKE_KW|MATCH */ -#line 987 "parse.y" +#line 993 "parse.y" {yymsp[0].minor.yy0=yymsp[0].minor.yy0;/*A-overwrites-X*/} -#line 3155 "parse.c" +#line 3161 "parse.c" break; case 168: /* likeop ::= NOT LIKE_KW|MATCH */ -#line 988 "parse.y" +#line 994 "parse.y" {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} -#line 3160 "parse.c" +#line 3166 "parse.c" break; case 169: /* expr ::= expr likeop expr */ -#line 989 "parse.y" +#line 995 "parse.y" { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; @@ -3171,10 +3177,10 @@ static void yy_reduce( yymsp[-2].minor.yy162.zEnd = yymsp[0].minor.yy162.zEnd; if( yymsp[-2].minor.yy162.pExpr ) yymsp[-2].minor.yy162.pExpr->flags |= EP_InfixFunc; } -#line 3175 "parse.c" +#line 3181 "parse.c" break; case 170: /* expr ::= expr likeop expr ESCAPE expr */ -#line 1000 "parse.y" +#line 1006 "parse.y" { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; @@ -3187,58 +3193,58 @@ static void yy_reduce( yymsp[-4].minor.yy162.zEnd = yymsp[0].minor.yy162.zEnd; if( yymsp[-4].minor.yy162.pExpr ) yymsp[-4].minor.yy162.pExpr->flags |= EP_InfixFunc; } -#line 3191 "parse.c" +#line 3197 "parse.c" break; case 171: /* expr ::= expr ISNULL|NOTNULL */ -#line 1027 "parse.y" +#line 1033 "parse.y" {spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy162,&yymsp[0].minor.yy0);} -#line 3196 "parse.c" +#line 3202 "parse.c" break; case 172: /* expr ::= expr NOT NULL */ -#line 1028 "parse.y" +#line 1034 "parse.y" {spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);} -#line 3201 "parse.c" +#line 3207 "parse.c" break; case 173: /* expr ::= expr IS expr */ -#line 1049 "parse.y" +#line 1055 "parse.y" { spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy162,&yymsp[0].minor.yy162); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy162.pExpr, yymsp[-2].minor.yy162.pExpr, TK_ISNULL); } -#line 3209 "parse.c" +#line 3215 "parse.c" break; case 174: /* expr ::= expr IS NOT expr */ -#line 1053 "parse.y" +#line 1059 "parse.y" { spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy162,&yymsp[0].minor.yy162); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy162.pExpr, yymsp[-3].minor.yy162.pExpr, TK_NOTNULL); } -#line 3217 "parse.c" +#line 3223 "parse.c" break; case 175: /* expr ::= NOT expr */ case 176: /* expr ::= BITNOT expr */ yytestcase(yyruleno==176); -#line 1077 "parse.y" +#line 1083 "parse.y" {spanUnaryPrefix(&yymsp[-1].minor.yy162,pParse,yymsp[-1].major,&yymsp[0].minor.yy162,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} -#line 3223 "parse.c" +#line 3229 "parse.c" break; case 177: /* expr ::= MINUS expr */ -#line 1081 "parse.y" +#line 1087 "parse.y" {spanUnaryPrefix(&yymsp[-1].minor.yy162,pParse,TK_UMINUS,&yymsp[0].minor.yy162,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} -#line 3228 "parse.c" +#line 3234 "parse.c" break; case 178: /* expr ::= PLUS expr */ -#line 1083 "parse.y" +#line 1089 "parse.y" {spanUnaryPrefix(&yymsp[-1].minor.yy162,pParse,TK_UPLUS,&yymsp[0].minor.yy162,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} -#line 3233 "parse.c" +#line 3239 "parse.c" break; case 179: /* between_op ::= BETWEEN */ case 182: /* in_op ::= IN */ yytestcase(yyruleno==182); -#line 1086 "parse.y" +#line 1092 "parse.y" {yymsp[0].minor.yy52 = 0;} -#line 3239 "parse.c" +#line 3245 "parse.c" break; case 181: /* expr ::= expr between_op expr AND expr */ -#line 1088 "parse.y" +#line 1094 "parse.y" { ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy162.pExpr); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy162.pExpr); @@ -3251,10 +3257,10 @@ static void yy_reduce( exprNot(pParse, yymsp[-3].minor.yy52, &yymsp[-4].minor.yy162); yymsp[-4].minor.yy162.zEnd = yymsp[0].minor.yy162.zEnd; } -#line 3255 "parse.c" +#line 3261 "parse.c" break; case 184: /* expr ::= expr in_op LP exprlist RP */ -#line 1104 "parse.y" +#line 1110 "parse.y" { if( yymsp[-1].minor.yy382==0 ){ /* Expressions of the form @@ -3265,7 +3271,7 @@ static void yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy162.pExpr); + sql_expr_free(pParse->db, yymsp[-4].minor.yy162.pExpr, false); yymsp[-4].minor.yy162.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy52],1); }else if( yymsp[-1].minor.yy382->nExpr==1 ){ /* Expressions of the form: @@ -3306,29 +3312,29 @@ static void yy_reduce( } yymsp[-4].minor.yy162.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } -#line 3310 "parse.c" +#line 3316 "parse.c" break; case 185: /* expr ::= LP select RP */ -#line 1155 "parse.y" +#line 1161 "parse.y" { spanSet(&yymsp[-2].minor.yy162,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy162.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0); sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy162.pExpr, yymsp[-1].minor.yy279); } -#line 3319 "parse.c" +#line 3325 "parse.c" break; case 186: /* expr ::= expr in_op LP select RP */ -#line 1160 "parse.y" +#line 1166 "parse.y" { yymsp[-4].minor.yy162.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy162.pExpr, 0); sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy162.pExpr, yymsp[-1].minor.yy279); exprNot(pParse, yymsp[-3].minor.yy52, &yymsp[-4].minor.yy162); yymsp[-4].minor.yy162.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } -#line 3329 "parse.c" +#line 3335 "parse.c" break; case 187: /* expr ::= expr in_op nm paren_exprlist */ -#line 1166 "parse.y" +#line 1172 "parse.y" { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); @@ -3338,20 +3344,20 @@ static void yy_reduce( exprNot(pParse, yymsp[-2].minor.yy52, &yymsp[-3].minor.yy162); yymsp[-3].minor.yy162.zEnd = &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; } -#line 3342 "parse.c" +#line 3348 "parse.c" break; case 188: /* expr ::= EXISTS LP select RP */ -#line 1175 "parse.y" +#line 1181 "parse.y" { Expr *p; spanSet(&yymsp[-3].minor.yy162,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ p = yymsp[-3].minor.yy162.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy279); } -#line 3352 "parse.c" +#line 3358 "parse.c" break; case 189: /* expr ::= CASE case_operand case_exprlist case_else END */ -#line 1184 "parse.y" +#line 1190 "parse.y" { spanSet(&yymsp[-4].minor.yy162,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/ yymsp[-4].minor.yy162.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy362, 0); @@ -3360,140 +3366,140 @@ static void yy_reduce( sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy162.pExpr); }else{ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy382); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy362); + sql_expr_free(pParse->db, yymsp[-1].minor.yy362, false); } } -#line 3367 "parse.c" +#line 3373 "parse.c" break; case 190: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ -#line 1197 "parse.y" +#line 1203 "parse.y" { yymsp[-4].minor.yy382 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy382, yymsp[-2].minor.yy162.pExpr); yymsp[-4].minor.yy382 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy382, yymsp[0].minor.yy162.pExpr); } -#line 3375 "parse.c" +#line 3381 "parse.c" break; case 191: /* case_exprlist ::= WHEN expr THEN expr */ -#line 1201 "parse.y" +#line 1207 "parse.y" { yymsp[-3].minor.yy382 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy162.pExpr); yymsp[-3].minor.yy382 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy382, yymsp[0].minor.yy162.pExpr); } -#line 3383 "parse.c" +#line 3389 "parse.c" break; case 194: /* case_operand ::= expr */ -#line 1211 "parse.y" +#line 1217 "parse.y" {yymsp[0].minor.yy362 = yymsp[0].minor.yy162.pExpr; /*A-overwrites-X*/} -#line 3388 "parse.c" +#line 3394 "parse.c" break; case 197: /* nexprlist ::= nexprlist COMMA expr */ -#line 1222 "parse.y" +#line 1228 "parse.y" {yymsp[-2].minor.yy382 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy382,yymsp[0].minor.yy162.pExpr);} -#line 3393 "parse.c" +#line 3399 "parse.c" break; case 198: /* nexprlist ::= expr */ -#line 1224 "parse.y" +#line 1230 "parse.y" {yymsp[0].minor.yy382 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy162.pExpr); /*A-overwrites-Y*/} -#line 3398 "parse.c" +#line 3404 "parse.c" break; case 200: /* paren_exprlist ::= LP exprlist RP */ case 205: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==205); -#line 1232 "parse.y" +#line 1238 "parse.y" {yymsp[-2].minor.yy382 = yymsp[-1].minor.yy382;} -#line 3404 "parse.c" +#line 3410 "parse.c" break; case 201: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm ON nm LP sortlist RP where_opt */ -#line 1239 "parse.y" +#line 1245 "parse.y" { sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0), yymsp[-2].minor.yy382, yymsp[-9].minor.yy52, &yymsp[-10].minor.yy0, yymsp[0].minor.yy362, SQLITE_SO_ASC, yymsp[-7].minor.yy52, SQLITE_IDXTYPE_APPDEF); } -#line 3413 "parse.c" +#line 3419 "parse.c" break; case 202: /* uniqueflag ::= UNIQUE */ case 243: /* raisetype ::= ABORT */ yytestcase(yyruleno==243); -#line 1246 "parse.y" +#line 1252 "parse.y" {yymsp[0].minor.yy52 = ON_CONFLICT_ACTION_ABORT;} -#line 3419 "parse.c" +#line 3425 "parse.c" break; case 203: /* uniqueflag ::= */ -#line 1247 "parse.y" +#line 1253 "parse.y" {yymsp[1].minor.yy52 = ON_CONFLICT_ACTION_NONE;} -#line 3424 "parse.c" +#line 3430 "parse.c" break; case 206: /* eidlist ::= eidlist COMMA nm collate sortorder */ -#line 1290 "parse.y" +#line 1296 "parse.y" { yymsp[-4].minor.yy382 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy382, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy52, yymsp[0].minor.yy52); } -#line 3431 "parse.c" +#line 3437 "parse.c" break; case 207: /* eidlist ::= nm collate sortorder */ -#line 1293 "parse.y" +#line 1299 "parse.y" { yymsp[-2].minor.yy382 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy52, yymsp[0].minor.yy52); /*A-overwrites-Y*/ } -#line 3438 "parse.c" +#line 3444 "parse.c" break; case 210: /* cmd ::= DROP INDEX ifexists fullname ON nm */ -#line 1304 "parse.y" +#line 1310 "parse.y" { sqlite3DropIndex(pParse, yymsp[-2].minor.yy387, &yymsp[0].minor.yy0, yymsp[-3].minor.yy52); } -#line 3445 "parse.c" +#line 3451 "parse.c" break; case 211: /* cmd ::= PRAGMA nm */ -#line 1311 "parse.y" +#line 1317 "parse.y" { sqlite3Pragma(pParse,&yymsp[0].minor.yy0,0,0,0,0); } -#line 3452 "parse.c" +#line 3458 "parse.c" break; case 212: /* cmd ::= PRAGMA nm EQ nmnum */ -#line 1314 "parse.y" +#line 1320 "parse.y" { sqlite3Pragma(pParse,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy0,0,0); } -#line 3459 "parse.c" +#line 3465 "parse.c" break; case 213: /* cmd ::= PRAGMA nm LP nmnum RP */ -#line 1317 "parse.y" +#line 1323 "parse.y" { sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,0,&yymsp[-1].minor.yy0,0,0); } -#line 3466 "parse.c" +#line 3472 "parse.c" break; case 214: /* cmd ::= PRAGMA nm EQ minus_num */ -#line 1320 "parse.y" +#line 1326 "parse.y" { sqlite3Pragma(pParse,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy0,0,1); } -#line 3473 "parse.c" +#line 3479 "parse.c" break; case 215: /* cmd ::= PRAGMA nm LP minus_num RP */ -#line 1323 "parse.y" +#line 1329 "parse.y" { sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,0,&yymsp[-1].minor.yy0,0,1); } -#line 3480 "parse.c" +#line 3486 "parse.c" break; case 216: /* cmd ::= PRAGMA nm EQ nm DOT nm */ -#line 1326 "parse.y" +#line 1332 "parse.y" { sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0,0); } -#line 3487 "parse.c" +#line 3493 "parse.c" break; case 217: /* cmd ::= PRAGMA */ -#line 1329 "parse.y" +#line 1335 "parse.y" { sqlite3Pragma(pParse, 0,0,0,0,0); } -#line 3494 "parse.c" +#line 3500 "parse.c" break; case 220: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ -#line 1349 "parse.y" +#line 1355 "parse.y" { Token all; all.z = yymsp[-3].minor.yy0.z; @@ -3501,124 +3507,124 @@ static void yy_reduce( pParse->initiateTTrans = false; sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all); } -#line 3505 "parse.c" +#line 3511 "parse.c" break; case 221: /* trigger_decl ::= TRIGGER ifnotexists nm trigger_time trigger_event ON fullname foreach_clause when_clause */ -#line 1359 "parse.y" +#line 1365 "parse.y" { sqlite3BeginTrigger(pParse, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy52, yymsp[-4].minor.yy10.a, yymsp[-4].minor.yy10.b, yymsp[-2].minor.yy387, yymsp[0].minor.yy362, yymsp[-7].minor.yy52); yymsp[-8].minor.yy0 = yymsp[-6].minor.yy0; /*yymsp[-8].minor.yy0-overwrites-T*/ } -#line 3513 "parse.c" +#line 3519 "parse.c" break; case 222: /* trigger_time ::= BEFORE */ -#line 1365 "parse.y" +#line 1371 "parse.y" { yymsp[0].minor.yy52 = TK_BEFORE; } -#line 3518 "parse.c" +#line 3524 "parse.c" break; case 223: /* trigger_time ::= AFTER */ -#line 1366 "parse.y" +#line 1372 "parse.y" { yymsp[0].minor.yy52 = TK_AFTER; } -#line 3523 "parse.c" +#line 3529 "parse.c" break; case 224: /* trigger_time ::= INSTEAD OF */ -#line 1367 "parse.y" +#line 1373 "parse.y" { yymsp[-1].minor.yy52 = TK_INSTEAD;} -#line 3528 "parse.c" +#line 3534 "parse.c" break; case 225: /* trigger_time ::= */ -#line 1368 "parse.y" +#line 1374 "parse.y" { yymsp[1].minor.yy52 = TK_BEFORE; } -#line 3533 "parse.c" +#line 3539 "parse.c" break; case 226: /* trigger_event ::= DELETE|INSERT */ case 227: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==227); -#line 1372 "parse.y" +#line 1378 "parse.y" {yymsp[0].minor.yy10.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy10.b = 0;} -#line 3539 "parse.c" +#line 3545 "parse.c" break; case 228: /* trigger_event ::= UPDATE OF idlist */ -#line 1374 "parse.y" +#line 1380 "parse.y" {yymsp[-2].minor.yy10.a = TK_UPDATE; yymsp[-2].minor.yy10.b = yymsp[0].minor.yy40;} -#line 3544 "parse.c" +#line 3550 "parse.c" break; case 229: /* when_clause ::= */ -#line 1381 "parse.y" +#line 1387 "parse.y" { yymsp[1].minor.yy362 = 0; } -#line 3549 "parse.c" +#line 3555 "parse.c" break; case 230: /* when_clause ::= WHEN expr */ -#line 1382 "parse.y" +#line 1388 "parse.y" { yymsp[-1].minor.yy362 = yymsp[0].minor.yy162.pExpr; } -#line 3554 "parse.c" +#line 3560 "parse.c" break; case 231: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ -#line 1386 "parse.y" +#line 1392 "parse.y" { assert( yymsp[-2].minor.yy427!=0 ); yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427; yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427; } -#line 3563 "parse.c" +#line 3569 "parse.c" break; case 232: /* trigger_cmd_list ::= trigger_cmd SEMI */ -#line 1391 "parse.y" +#line 1397 "parse.y" { assert( yymsp[-1].minor.yy427!=0 ); yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427; } -#line 3571 "parse.c" +#line 3577 "parse.c" break; case 233: /* trnm ::= nm DOT nm */ -#line 1402 "parse.y" +#line 1408 "parse.y" { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, "qualified table names are not allowed on INSERT, UPDATE, and DELETE " "statements within triggers"); } -#line 3581 "parse.c" +#line 3587 "parse.c" break; case 234: /* tridxby ::= INDEXED BY nm */ -#line 1414 "parse.y" +#line 1420 "parse.y" { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } -#line 3590 "parse.c" +#line 3596 "parse.c" break; case 235: /* tridxby ::= NOT INDEXED */ -#line 1419 "parse.y" +#line 1425 "parse.y" { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } -#line 3599 "parse.c" +#line 3605 "parse.c" break; case 236: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ -#line 1432 "parse.y" +#line 1438 "parse.y" {yymsp[-6].minor.yy427 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy382, yymsp[0].minor.yy362, yymsp[-5].minor.yy52);} -#line 3604 "parse.c" +#line 3610 "parse.c" break; case 237: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */ -#line 1436 "parse.y" +#line 1442 "parse.y" {yymsp[-4].minor.yy427 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy40, yymsp[0].minor.yy279, yymsp[-4].minor.yy52);/*A-overwrites-R*/} -#line 3609 "parse.c" +#line 3615 "parse.c" break; case 238: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ -#line 1440 "parse.y" +#line 1446 "parse.y" {yymsp[-4].minor.yy427 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy362);} -#line 3614 "parse.c" +#line 3620 "parse.c" break; case 239: /* trigger_cmd ::= select */ -#line 1444 "parse.y" +#line 1450 "parse.y" {yymsp[0].minor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy279); /*A-overwrites-X*/} -#line 3619 "parse.c" +#line 3625 "parse.c" break; case 240: /* expr ::= RAISE LP IGNORE RP */ -#line 1447 "parse.y" +#line 1453 "parse.y" { spanSet(&yymsp[-3].minor.yy162,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ yymsp[-3].minor.yy162.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0); @@ -3626,10 +3632,10 @@ static void yy_reduce( yymsp[-3].minor.yy162.pExpr->affinity = ON_CONFLICT_ACTION_IGNORE; } } -#line 3630 "parse.c" +#line 3636 "parse.c" break; case 241: /* expr ::= RAISE LP raisetype COMMA STRING RP */ -#line 1454 "parse.y" +#line 1460 "parse.y" { spanSet(&yymsp[-5].minor.yy162,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ yymsp[-5].minor.yy162.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); @@ -3637,85 +3643,85 @@ static void yy_reduce( yymsp[-5].minor.yy162.pExpr->affinity = (char)yymsp[-3].minor.yy52; } } -#line 3641 "parse.c" +#line 3647 "parse.c" break; case 242: /* raisetype ::= ROLLBACK */ -#line 1464 "parse.y" +#line 1470 "parse.y" {yymsp[0].minor.yy52 = ON_CONFLICT_ACTION_ROLLBACK;} -#line 3646 "parse.c" +#line 3652 "parse.c" break; case 244: /* raisetype ::= FAIL */ -#line 1466 "parse.y" +#line 1472 "parse.y" {yymsp[0].minor.yy52 = ON_CONFLICT_ACTION_FAIL;} -#line 3651 "parse.c" +#line 3657 "parse.c" break; case 245: /* cmd ::= DROP TRIGGER ifexists fullname */ -#line 1471 "parse.y" +#line 1477 "parse.y" { sqlite3DropTrigger(pParse,yymsp[0].minor.yy387,yymsp[-1].minor.yy52); } -#line 3658 "parse.c" +#line 3664 "parse.c" break; case 246: /* cmd ::= REINDEX */ -#line 1478 "parse.y" +#line 1484 "parse.y" {sqlite3Reindex(pParse, 0, 0);} -#line 3663 "parse.c" +#line 3669 "parse.c" break; case 247: /* cmd ::= REINDEX nm */ -#line 1479 "parse.y" +#line 1485 "parse.y" {sqlite3Reindex(pParse, &yymsp[0].minor.yy0, 0);} -#line 3668 "parse.c" +#line 3674 "parse.c" break; case 248: /* cmd ::= REINDEX nm ON nm */ -#line 1480 "parse.y" +#line 1486 "parse.y" {sqlite3Reindex(pParse, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} -#line 3673 "parse.c" +#line 3679 "parse.c" break; case 249: /* cmd ::= ANALYZE */ -#line 1485 "parse.y" +#line 1491 "parse.y" {sqlite3Analyze(pParse, 0);} -#line 3678 "parse.c" +#line 3684 "parse.c" break; case 250: /* cmd ::= ANALYZE nm */ -#line 1486 "parse.y" +#line 1492 "parse.y" {sqlite3Analyze(pParse, &yymsp[0].minor.yy0);} -#line 3683 "parse.c" +#line 3689 "parse.c" break; case 251: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ -#line 1491 "parse.y" +#line 1497 "parse.y" { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy387,&yymsp[0].minor.yy0); } -#line 3690 "parse.c" +#line 3696 "parse.c" break; case 252: /* with ::= */ -#line 1514 "parse.y" +#line 1520 "parse.y" {yymsp[1].minor.yy151 = 0;} -#line 3695 "parse.c" +#line 3701 "parse.c" break; case 253: /* with ::= WITH wqlist */ -#line 1516 "parse.y" +#line 1522 "parse.y" { yymsp[-1].minor.yy151 = yymsp[0].minor.yy151; } -#line 3700 "parse.c" +#line 3706 "parse.c" break; case 254: /* with ::= WITH RECURSIVE wqlist */ -#line 1517 "parse.y" +#line 1523 "parse.y" { yymsp[-2].minor.yy151 = yymsp[0].minor.yy151; } -#line 3705 "parse.c" +#line 3711 "parse.c" break; case 255: /* wqlist ::= nm eidlist_opt AS LP select RP */ -#line 1519 "parse.y" +#line 1525 "parse.y" { yymsp[-5].minor.yy151 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy382, yymsp[-1].minor.yy279); /*A-overwrites-X*/ } -#line 3712 "parse.c" +#line 3718 "parse.c" break; case 256: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ -#line 1522 "parse.y" +#line 1528 "parse.y" { yymsp[-7].minor.yy151 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy151, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy382, yymsp[-1].minor.yy279); } -#line 3719 "parse.c" +#line 3725 "parse.c" break; default: /* (257) input ::= ecmd */ yytestcase(yyruleno==257); @@ -3826,7 +3832,7 @@ static void yy_syntax_error( } else { sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); } -#line 3830 "parse.c" +#line 3836 "parse.c" /************ End %syntax_error code ******************************************/ sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index e2acf24..9ee7dac 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -108,7 +108,10 @@ static void disableLookaside(Parse *pParse){ // Input is a single SQL command input ::= ecmd. -ecmd ::= explain cmdx SEMI. { sqlite3FinishCoding(pParse); } +ecmd ::= explain cmdx SEMI. { + if (!pParse->parse_only) + sqlite3FinishCoding(pParse); +} ecmd ::= SEMI. { sqlite3ErrorMsg(pParse, "syntax error: empty request"); } @@ -378,7 +381,10 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { // cmd ::= select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, X, &dest); + if(!pParse->parse_only) + sqlite3Select(pParse, X, &dest); + else + sql_expr_extract_select(pParse, X); sqlite3SelectDelete(pParse->db, X); } @@ -627,7 +633,7 @@ joinop(X) ::= JOIN_KW(A) join_nm(B) join_nm(C) JOIN. {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/} %type on_opt {Expr*} -%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);} +%destructor on_opt {sql_expr_free(pParse->db, $$, false);} on_opt(N) ::= ON expr(E). {N = E.pExpr;} on_opt(N) ::= . {N = 0;} @@ -685,7 +691,7 @@ groupby_opt(A) ::= . {A = 0;} groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;} %type having_opt {Expr*} -%destructor having_opt {sqlite3ExprDelete(pParse->db, $$);} +%destructor having_opt {sql_expr_free(pParse->db, $$, false);} having_opt(A) ::= . {A = 0;} having_opt(A) ::= HAVING expr(X). {A = X.pExpr;} @@ -735,7 +741,7 @@ cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { %endif %type where_opt {Expr*} -%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} +%destructor where_opt {sql_expr_free(pParse->db, $$, false);} where_opt(A) ::= . {A = 0;} where_opt(A) ::= WHERE expr(X). {A = X.pExpr;} @@ -824,9 +830,9 @@ idlist(A) ::= nm(Y). // %type expr {ExprSpan} -%destructor expr {sqlite3ExprDelete(pParse->db, $$.pExpr);} +%destructor expr {sql_expr_free(pParse->db, $$.pExpr, false);} %type term {ExprSpan} -%destructor term {sqlite3ExprDelete(pParse->db, $$.pExpr);} +%destructor term {sql_expr_free(pParse->db, $$.pExpr, false);} %include { /* This is a utility routine used to set the ExprSpan.zStart and @@ -1034,7 +1040,7 @@ expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);} sqlite3 *db = pParse->db; if( pA && pY && pY->op==TK_NULL ){ pA->op = (u8)op; - sqlite3ExprDelete(db, pA->pRight); + sql_expr_free(db, pA->pRight, false); pA->pRight = 0; } } @@ -1111,7 +1117,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprDelete(pParse->db, A.pExpr); + sql_expr_free(pParse->db, A.pExpr, false); A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); }else if( Y->nExpr==1 ){ /* Expressions of the form: @@ -1189,7 +1195,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); }else{ sqlite3ExprListDelete(pParse->db, Y); - sqlite3ExprDelete(pParse->db, Z); + sql_expr_free(pParse->db, Z, false); } } %type case_exprlist {ExprList*} @@ -1203,11 +1209,11 @@ case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). { A = sqlite3ExprListAppend(pParse,A, Z.pExpr); } %type case_else {Expr*} -%destructor case_else {sqlite3ExprDelete(pParse->db, $$);} +%destructor case_else {sql_expr_free(pParse->db, $$, false);} case_else(A) ::= ELSE expr(X). {A = X.pExpr;} case_else(A) ::= . {A = 0;} %type case_operand {Expr*} -%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);} +%destructor case_operand {sql_expr_free(pParse->db, $$, false);} case_operand(A) ::= expr(X). {A = X.pExpr; /*A-overwrites-X*/} case_operand(A) ::= . {A = 0;} @@ -1377,7 +1383,7 @@ foreach_clause ::= . foreach_clause ::= FOR EACH ROW. %type when_clause {Expr*} -%destructor when_clause {sqlite3ExprDelete(pParse->db, $$);} +%destructor when_clause {sql_expr_free(pParse->db, $$, false);} when_clause(A) ::= . { A = 0; } when_clause(A) ::= WHEN expr(X). { A = X.pExpr; } diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c index 18e25cf..63997f2 100644 --- a/src/box/sql/resolve.c +++ b/src/box/sql/resolve.c @@ -115,7 +115,7 @@ resolveAlias(Parse * pParse, /* Parsing context */ } ExprSetProperty(pDup, EP_Alias); - /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This + /* Before calling sql_expr_free(), set the EP_Static flag. This * prevents ExprDelete() from deleting the Expr structure itself, * allowing it to be repopulated by the memcpy() on the following line. * The pExpr->u.zToken might point into memory that will be freed by the @@ -123,7 +123,7 @@ resolveAlias(Parse * pParse, /* Parsing context */ * make a copy of the token before doing the sqlite3DbFree(). */ ExprSetProperty(pExpr, EP_Static); - sqlite3ExprDelete(db, pExpr); + sql_expr_free(db, pExpr, false); memcpy(pExpr, pDup, sizeof(*pExpr)); if (!ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken != 0) { assert((pExpr->flags & (EP_Reduced | EP_TokenOnly)) == 0); @@ -462,9 +462,9 @@ lookupName(Parse * pParse, /* The parsing context */ /* Clean up and return */ - sqlite3ExprDelete(db, pExpr->pLeft); + sql_expr_free(db, pExpr->pLeft, false); pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); + sql_expr_free(db, pExpr->pRight, false); pExpr->pRight = 0; pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); lookupname_end: @@ -1030,7 +1030,7 @@ resolveCompoundOrderBy(Parse * pParse, /* Parsing context. Leave error messages resolveOrderByTermToExprList (pParse, pSelect, pDup); } - sqlite3ExprDelete(db, pDup); + sql_expr_free(db, pDup, false); } } if (iCol > 0) { @@ -1052,7 +1052,7 @@ resolveCompoundOrderBy(Parse * pParse, /* Parsing context. Leave error messages assert(pParent->pLeft == pE); pParent->pLeft = pNew; } - sqlite3ExprDelete(db, pE); + sql_expr_free(db, pE, false); pItem->u.x.iOrderByCol = (u16) iCol; pItem->done = 1; } else { diff --git a/src/box/sql/select.c b/src/box/sql/select.c index c14bd74..cd1bb77 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -94,12 +94,12 @@ clearSelect(sqlite3 * db, Select * p, int bFree) Select *pPrior = p->pPrior; sqlite3ExprListDelete(db, p->pEList); sqlite3SrcListDelete(db, p->pSrc); - sqlite3ExprDelete(db, p->pWhere); + sql_expr_free(db, p->pWhere, false); sqlite3ExprListDelete(db, p->pGroupBy); - sqlite3ExprDelete(db, p->pHaving); + sql_expr_free(db, p->pHaving, false); sqlite3ExprListDelete(db, p->pOrderBy); - sqlite3ExprDelete(db, p->pLimit); - sqlite3ExprDelete(db, p->pOffset); + sql_expr_free(db, p->pLimit, false); + sql_expr_free(db, p->pOffset, false); if (p->pWith) sqlite3WithDelete(db, p->pWith); if (bFree) @@ -2669,7 +2669,7 @@ multiSelect(Parse * pParse, /* Parsing context */ pPrior-> nSelectRow); } - sqlite3ExprDelete(db, p->pLimit); + sql_expr_free(db, p->pLimit, false); p->pLimit = pLimit; p->pOffset = pOffset; p->iLimit = 0; @@ -2768,7 +2768,7 @@ multiSelect(Parse * pParse, /* Parsing context */ p->pPrior = pPrior; if (p->nSelectRow > pPrior->nSelectRow) p->nSelectRow = pPrior->nSelectRow; - sqlite3ExprDelete(db, p->pLimit); + sql_expr_free(db, p->pLimit, false); p->pLimit = pLimit; p->pOffset = pOffset; @@ -3297,9 +3297,9 @@ multiSelectOrderBy(Parse * pParse, /* Parsing context */ } else { regLimitA = regLimitB = 0; } - sqlite3ExprDelete(db, p->pLimit); + sql_expr_free(db, p->pLimit, false); p->pLimit = 0; - sqlite3ExprDelete(db, p->pOffset); + sql_expr_free(db, p->pOffset, false); p->pOffset = 0; regAddrA = ++pParse->nMem; @@ -3514,7 +3514,7 @@ substExpr(Parse * pParse, /* Report errors here */ pExpr->iRightJoinTable; pNew->flags |= EP_FromJoin; } - sqlite3ExprDelete(db, pExpr); + sql_expr_free(db, pExpr, false); pExpr = pNew; } } @@ -6334,3 +6334,13 @@ sqlite3Select(Parse * pParse, /* The parser context */ #endif return rc; } + +void +sql_expr_extract_select(struct Parse *parser, struct Select *select) +{ + struct ExprList *expr_list = select->pEList; + assert(expr_list->nExpr == 1); + parser->parsed_expr = sqlite3ExprDup(parser->db, + expr_list->a->pExpr, + EXPRDUP_REDUCE); +} diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index e9c0b31..df13380 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -63,10 +63,12 @@ * asterisks and the comment text. */ -#include #include -#include + +#include "box/field_def.h" +#include "box/sql.h" #include "box/txn.h" +#include "trivia/util.h" /* * These #defines should enable >2GB file support on POSIX if the @@ -3007,6 +3009,10 @@ struct Parse { With *pWithToFree; /* Free this WITH object at the end of the parse */ bool initiateTTrans; /* Initiate Tarantool transaction */ + /** If set - do not emit byte code at all, just parse. */ + bool parse_only; + /** If parse_only is set to true, store parsed expression. */ + struct Expr *parsed_expr; }; /* @@ -3521,7 +3527,6 @@ void sqlite3PExprAddSelect(Parse *, Expr *, Select *); Expr *sqlite3ExprAnd(sqlite3 *, Expr *, Expr *); Expr *sqlite3ExprFunction(Parse *, ExprList *, Token *); void sqlite3ExprAssignVarNumber(Parse *, Expr *, u32); -void sqlite3ExprDelete(sqlite3 *, Expr *); ExprList *sqlite3ExprListAppend(Parse *, ExprList *, Expr *); ExprList *sqlite3ExprListAppendVector(Parse *, ExprList *, IdList *, Expr *); void sqlite3ExprListSetSortOrder(ExprList *, int); diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c index f810db4..67d8cce 100644 --- a/src/box/sql/tokenize.c +++ b/src/box/sql/tokenize.c @@ -652,3 +652,112 @@ sqlite3RunParser(Parse * pParse, const char *zSql, char **pzErrMsg) assert(nErr == 0 || pParse->rc != SQLITE_OK); return nErr; } + +int +sql_expr_compile(sqlite3 *db, + const char *expr, + struct Expr **result, + char **err) +{ + struct Parse parser; + int nErr = 0; /* Number of errors encountered */ + int i; /* Loop counter */ + void *engine; /* The LEMON-generated LALR(1) parser */ + int token_type; /* type of the next token */ + int last_token_type = -1; /* type of the previous token */ + int mxSqlLen; /* Max length of an SQL string */ + + assert(expr != 0); + mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + memset(&parser, 0, sizeof(struct Parse)); + parser.rc = SQLITE_OK; + parser.zTail = expr; + parser.db = db; + parser.pToplevel = NULL; + parser.parse_only = true; + i = 0; + assert(err != 0); + engine = sqlite3ParserAlloc(sqlite3Malloc); + if (engine == NULL) { + sqlite3OomFault(db); + return SQLITE_NOMEM_BKPT; + } + + const char *outer = "SELECT "; + char *stmt = (char*)region_alloc(&fiber()->gc, strlen(outer) + strlen(expr) + 1); + if (stmt == NULL) { + sqlite3OomFault(db); + return SQLITE_NOMEM_BKPT; + } + sprintf(stmt, "%s%s", outer, expr); + while (true) { + assert(i >= 0); + if (stmt[i] != 0) { + parser.sLastToken.z = &stmt[i]; + parser.sLastToken.n = + sqlite3GetToken((u8 *) & stmt[i], &token_type, + &parser.sLastToken.isReserved); + i += parser.sLastToken.n; + if (i > mxSqlLen) { + parser.rc = SQLITE_TOOBIG; + break; + } + } else { + /* Upon reaching the end of input, call + * the parser two more times with tokens + * TK_SEMI and 0, in that order. + */ + if (last_token_type == TK_SEMI) + token_type = 0; + else if (last_token_type == 0) + break; + else + token_type = TK_SEMI; + } + if (token_type >= TK_SPACE) { + assert(token_type == TK_SPACE + || token_type == TK_ILLEGAL); + if (token_type == TK_ILLEGAL) { + sqlite3ErrorMsg(&parser, + "unrecognized token: \"%T\"", + &parser.sLastToken); + break; + } + } else { + sqlite3Parser(engine, token_type, parser.sLastToken, + &parser); + last_token_type = token_type; + if (parser.rc != SQLITE_OK || db->mallocFailed) + break; + } + } + assert(nErr == 0); + assert(stmt[i] == '\0'); + sqlite3ParserFree(engine, sqlite3_free); + if (db->mallocFailed) + parser.rc = SQLITE_NOMEM_BKPT; + if (parser.rc != SQLITE_OK && parser.rc != SQLITE_DONE + && parser.zErrMsg == 0) { + parser.zErrMsg = + sqlite3MPrintf(db, "%s", sqlite3ErrStr(parser.rc)); + } + assert(err != 0); + if (parser.zErrMsg) { + *err = parser.zErrMsg; + sqlite3_log(parser.rc, "%s", *err); + parser.zErrMsg = 0; + nErr++; + } + + assert(parser.pVdbe == NULL); + assert(parser.pNewTable == NULL); + assert(parser.pWithToFree == NULL); + assert(parser.pAinc == NULL); + assert(parser.pZombieTab == NULL); + assert(parser.pNewTrigger == NULL); + assert(parser.pVList == NULL); + + assert(nErr == 0 || parser.rc != SQLITE_OK); + *result = parser.parsed_expr; + return nErr; +} diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c index 5460d1a..0cf3712 100644 --- a/src/box/sql/trigger.c +++ b/src/box/sql/trigger.c @@ -52,7 +52,7 @@ sqlite3DeleteTriggerStep(sqlite3 * db, TriggerStep * pTriggerStep) TriggerStep *pTmp = pTriggerStep; pTriggerStep = pTriggerStep->pNext; - sqlite3ExprDelete(db, pTmp->pWhere); + sql_expr_free(db, pTmp->pWhere, false); sqlite3ExprListDelete(db, pTmp->pExprList); sqlite3SelectDelete(db, pTmp->pSelect); sqlite3IdListDelete(db, pTmp->pIdList); @@ -185,7 +185,7 @@ sqlite3BeginTrigger(Parse * pParse, /* The parse context of the CREATE TRIGGER s sqlite3DbFree(db, zName); sqlite3SrcListDelete(db, pTableName); sqlite3IdListDelete(db, pColumns); - sqlite3ExprDelete(db, pWhen); + sql_expr_free(db, pWhen, false); if (!pParse->pNewTrigger) { sqlite3DeleteTrigger(db, pTrigger); } else { @@ -447,7 +447,7 @@ sqlite3TriggerUpdateStep(sqlite3 * db, /* The database connection */ pTriggerStep->orconf = orconf; } sqlite3ExprListDelete(db, pEList); - sqlite3ExprDelete(db, pWhere); + sql_expr_free(db, pWhere, false); return pTriggerStep; } @@ -470,7 +470,7 @@ sqlite3TriggerDeleteStep(sqlite3 * db, /* Database connection */ sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); pTriggerStep->orconf = ON_CONFLICT_ACTION_DEFAULT; } - sqlite3ExprDelete(db, pWhere); + sql_expr_free(db, pWhere, false); return pTriggerStep; } @@ -485,7 +485,7 @@ sqlite3DeleteTrigger(sqlite3 * db, Trigger * pTrigger) sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); - sqlite3ExprDelete(db, pTrigger->pWhen); + sql_expr_free(db, pTrigger->pWhen, false); sqlite3IdListDelete(db, pTrigger->pColumns); sqlite3DbFree(db, pTrigger); } @@ -911,7 +911,7 @@ codeRowTrigger(Parse * pParse, /* Current parse context */ iEndTrigger, SQLITE_JUMPIFNULL); } - sqlite3ExprDelete(db, pWhen); + sql_expr_free(db, pWhen, false); } /* Code the trigger program into the sub-vdbe. */ diff --git a/src/box/sql/update.c b/src/box/sql/update.c index bf41325..7727ae5 100644 --- a/src/box/sql/update.c +++ b/src/box/sql/update.c @@ -667,7 +667,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pChanges); - sqlite3ExprDelete(db, pWhere); + sql_expr_free(db, pWhere, false); return; } diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c index 568ef99..8b06bae 100644 --- a/src/box/sql/wherecode.c +++ b/src/box/sql/wherecode.c @@ -1830,7 +1830,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t pLevel->iIdxCur = iCovCur; if (pAndExpr) { pAndExpr->pLeft = 0; - sqlite3ExprDelete(db, pAndExpr); + sql_expr_free(db, pAndExpr, false); } sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeGoto(v, pLevel->addrBrk); diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c index 26dcd6a..ccdff46 100644 --- a/src/box/sql/whereexpr.c +++ b/src/box/sql/whereexpr.c @@ -97,7 +97,7 @@ whereClauseInsert(WhereClause * pWC, Expr * p, u16 wtFlags) sizeof(pWC->a[0]) * pWC->nSlot * 2); if (pWC->a == 0) { if (wtFlags & TERM_DYNAMIC) { - sqlite3ExprDelete(db, p); + sql_expr_free(db, p, false); } pWC->a = pOld; return 0; @@ -1057,7 +1057,7 @@ exprAnalyze(SrcList * pSrc, /* the FROM clause */ int idxNew; pDup = sqlite3ExprDup(db, pExpr, 0); if (db->mallocFailed) { - sqlite3ExprDelete(db, pDup); + sql_expr_free(db, pDup, false); return; } idxNew = @@ -1398,7 +1398,7 @@ sqlite3WhereClauseClear(WhereClause * pWC) sqlite3 *db = pWC->pWInfo->pParse->db; for (i = pWC->nTerm - 1, a = pWC->a; i >= 0; i--, a++) { if (a->wtFlags & TERM_DYNAMIC) { - sqlite3ExprDelete(db, a->pExpr); + sql_expr_free(db, a->pExpr, false); } if (a->wtFlags & TERM_ORINFO) { whereOrInfoDelete(db, a->u.pOrInfo); -- 2.11.0