* [tarantool-patches] [PATCH] sql: move default col values to Tarantool's core
2018-03-31 3:55 ` Kirill Yukhin
@ 2018-03-31 4:24 ` Kirill Yukhin
2018-04-03 6:29 ` [tarantool-patches] Re: [PATCH 3/3] " Kirill Yukhin
1 sibling, 0 replies; 8+ messages in thread
From: Kirill Yukhin @ 2018-03-31 4:24 UTC (permalink / raw)
To: v.shpilevoy; +Cc: tarantool-patches
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 <stdbool.h>
+#include <stdint.h>
+
#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 <box/field_def.h>
#include <stdbool.h>
-#include <trivia/util.h>
+
+#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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [tarantool-patches] Re: [PATCH 3/3] sql: move default col values to Tarantool's core
2018-03-31 3:55 ` Kirill Yukhin
2018-03-31 4:24 ` [tarantool-patches] [PATCH] " Kirill Yukhin
@ 2018-04-03 6:29 ` Kirill Yukhin
1 sibling, 0 replies; 8+ messages in thread
From: Kirill Yukhin @ 2018-04-03 6:29 UTC (permalink / raw)
To: v.shpilevoy; +Cc: tarantool-patches
Hello,
Vlad removed one more memory issue and refactored sql_expr_compile().
I am completely OK w/ his changes and will push it to 2.x branch.
Final patch in the bottom.
--
Regards, Kirill Yukhin
sql: move default col values to Tarantool's core
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
25 files changed, 909 insertions(+), 637 deletions(-)
src/CMakeLists.txt | 2 +-
src/box/alter.cc | 23 +-
src/box/box.cc | 3 +-
src/box/field_def.c | 5 +-
src/box/field_def.h | 4 +
src/box/space_def.c | 127 +++++--
src/box/space_def.h | 18 +-
src/box/sql.c | 51 ++-
src/box/sql.h | 90 ++++-
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 | 31 +-
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 | 26 ++
src/box/sql/trigger.c | 12 +-
src/box/sql/update.c | 2 +-
src/box/sql/wherecode.c | 2 +-
src/box/sql/whereexpr.c | 6 +-
modified 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})
modified 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,11 @@ 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 &&
+ sql_expr_compile(sql_get(), field->default_value,
+ &field->default_value_expr) != 0)
+ diag_raise();
}
/**
@@ -429,10 +435,20 @@ space_format_decode(const char *data, uint32_t *out_count,
size_t size = count * sizeof(struct field_def);
struct field_def *region_defs =
(struct field_def *) region_alloc_xc(region, size);
+ /*
+ * Nullify to prevent a case when decoding will fail in
+ * the middle and space_def_destroy_fields() below will
+ * work with garbage pointers.
+ */
+ memset(region_defs, 0, size);
+ auto fields_guard = make_scoped_guard([=] {
+ space_def_destroy_fields(region_defs, count);
+ });
for (uint32_t i = 0; i < count; ++i) {
field_def_decode(®ion_defs[i], &data, space_name, name_len,
errcode, i, region);
}
+ fields_guard.is_active = false;
return region_defs;
}
@@ -488,6 +504,9 @@ space_def_new_from_tuple(struct tuple *tuple, uint32_t errcode,
MP_ARRAY);
fields = space_format_decode(format, &field_count, name,
name_len, errcode, region);
+ auto fields_guard = make_scoped_guard([=] {
+ space_def_destroy_fields(fields, field_count);
+ });
if (exact_field_count != 0 &&
exact_field_count < field_count) {
tnt_raise(ClientError, errcode, tt_cstr(name, name_len),
@@ -1455,9 +1474,9 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
struct space_def *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); });
+ access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_C, true);
RLIST_HEAD(empty_list);
struct space *space = space_new_xc(def, &empty_list);
/**
@@ -1515,9 +1534,9 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
struct space_def *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); });
+ access_check_ddl(def->name, def->uid, SC_SPACE, PRIV_A, true);
/*
* Check basic options. Assume the space to be
* empty, because we can not calculate here
modified src/box/box.cc
@@ -1760,6 +1760,7 @@ box_cfg_xc(void)
replication_init();
port_init();
iproto_init();
+ sql_init();
wal_thread_start();
title("loading");
@@ -1956,7 +1957,7 @@ box_cfg_xc(void)
/* Follow replica */
replicaset_follow();
- sql_init();
+ sql_load_schema();
say_info("ready to accept requests");
modified 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
modified 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)
modified 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,47 @@ 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) {
+ assert(fields[i].default_value_expr != NULL);
+ int len = strlen(fields[i].default_value);
+ field_strs_size += len + 1;
+ 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 +106,33 @@ 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 *e =
+ src->fields[i].default_value_expr;
+ assert(e != NULL);
+ char *expr_pos_old = expr_pos;
+ e = sql_expr_dup(sql_get(), e, 0, &expr_pos);
+ assert(e != NULL);
+ /* 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 +146,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");
@@ -150,15 +183,42 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count,
if (field_count == 0) {
def->fields = NULL;
} else {
- char *name_pos = (char *)def + names_offset;
+ 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 *e =
+ fields[i].default_value_expr;
+ assert(e != NULL);
+ char *expr_pos_old = expr_pos;
+ e = sql_expr_dup(sql_get(), e, 0, &expr_pos);
+ assert(e != NULL);
+ /* 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);
+ def->fields[i].default_value_expr = e;
+ }
}
}
return def;
@@ -217,3 +277,24 @@ space_def_check_compatibility(const struct space_def *old_def,
return 0;
}
+/** Free a default value's syntax trees of @a defs. */
+void
+space_def_destroy_fields(struct field_def *fields, uint32_t field_count)
+{
+ for (uint32_t i = 0; i < field_count; ++i) {
+ if (fields[i].default_value_expr != NULL) {
+ sql_expr_free(sql_get(), fields[i].default_value_expr,
+ true);
+ }
+ }
+}
+
+void
+space_def_delete(struct space_def *def)
+{
+ space_opts_destroy(&def->opts);
+ tuple_dictionary_unref(def->dict);
+ space_def_destroy_fields(def->fields, def->field_count);
+ TRASH(def);
+ free(def);
+}
modified src/box/space_def.h
@@ -111,18 +111,20 @@ struct space_def {
char name[0];
};
+/*
+ * Free a default value syntax trees of @a defs.
+ * @param fields Fields array to destroy.
+ * @param field_count Length of @a fields.
+ */
+void
+space_def_destroy_fields(struct field_def *fields, uint32_t field_count);
+
/**
* 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.
modified 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;
@@ -1451,11 +1472,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);
@@ -1477,6 +1504,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);
}
@@ -1670,3 +1703,17 @@ tarantoolSqlNextSeqId(uint64_t *max_id)
return tuple_field_u64(tuple, BOX_SEQUENCE_FIELD_ID, 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;
+}
modified src/box/sql.h
@@ -31,6 +31,9 @@
* SUCH DAMAGE.
*/
+#include <stdbool.h>
+#include <stdint.h>
+
#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,92 @@ 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.
+ *
+ * @retval Error code if any.
+ */
+int
+sql_expr_compile(struct sqlite3 *db, const char *expr, struct Expr **result);
+
+/**
+ * Store duplicate of a parsed expression into @a parser.
+ * @param parser Parser context.
+ * @param select Select to extract from.
+ */
+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
modified src/box/sql/build.c
@@ -286,7 +286,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);
@@ -366,7 +366,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);
@@ -893,7 +893,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,
@@ -905,7 +905,7 @@ sqlite3AddDefaultValue(Parse * pParse, ExprSpan * pSpan)
sqlite3DbFree(db, x.u.zToken);
}
}
- sqlite3ExprDelete(db, pSpan->pExpr);
+ sql_expr_free(db, pSpan->pExpr, false);
}
@@ -1019,9 +1019,7 @@ sqlite3AddCheckConstraint(Parse * pParse, /* Parsing context */
}
} else
#endif
- {
- sqlite3ExprDelete(pParse->db, pCheckExpr);
- }
+ sql_expr_free(pParse->db, pCheckExpr, false);
}
/*
@@ -3256,7 +3254,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);
@@ -3728,7 +3726,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);
@@ -3784,7 +3782,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;
modified 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
modified 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);
}
/*
modified 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) {
modified src/box/sql/insert.c
@@ -346,6 +346,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 */
@@ -382,6 +383,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
*/
@@ -677,13 +680,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);
@@ -754,8 +762,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)
@@ -1112,10 +1124,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
@@ -1151,7 +1166,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;
modified 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);
modified 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 */
}
modified 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; }
modified 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 {
modified 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;
}
}
@@ -6333,3 +6333,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);
+}
modified src/box/sql/sqliteInt.h
@@ -63,10 +63,12 @@
* asterisks and the comment text.
*/
-#include <box/field_def.h>
#include <stdbool.h>
-#include <trivia/util.h>
+
+#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;
};
/*
@@ -3526,7 +3532,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);
modified src/box/sql/tokenize.c
@@ -652,3 +652,29 @@ 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)
+{
+ const char *outer = "SELECT ";
+ int len = strlen(outer) + strlen(expr);
+ char *stmt = (char *) region_alloc(&fiber()->gc, len + 1);
+ if (stmt == NULL) {
+ diag_set(OutOfMemory, len + 1, "region_alloc", "stmt");
+ return -1;
+ }
+ sprintf(stmt, "%s%s", outer, expr);
+
+ struct Parse parser;
+ memset(&parser, 0, sizeof(parser));
+ parser.db = db;
+ parser.parse_only = true;
+ char *unused;
+ if (sqlite3RunParser(&parser, stmt, &unused) != SQLITE_OK) {
+ diag_set(ClientError, ER_SQL_EXECUTE, expr);
+ return -1;
+ }
+ *result = parser.parsed_expr;
+ sqlite3ParserReset(&parser);
+ return 0;
+}
modified 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);
}
@@ -910,7 +910,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. */
modified 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;
}
modified 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);
modified 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);
^ permalink raw reply [flat|nested] 8+ messages in thread