From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, korablev@tarantool.org Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [tarantool-patches] [PATCH v2 8/9] box: exported sql_bind structure and API Date: Wed, 30 Jan 2019 11:59:15 +0300 [thread overview] Message-ID: <1c364cb9d4584a5c7d1375a121f794a680efbc3f.1548838034.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1548838034.git.kshcherbatov@tarantool.org> Refactored sql_bind structure, sql_bind_decode, sql_bind_column and sql_bind routines in separate module bind.h. We need SQL bindings in future for check constraints. Needed for #3691 --- src/box/CMakeLists.txt | 1 + src/box/bind.c | 239 ++++++++++++++++++++++++++++++++++++ src/box/bind.h | 138 +++++++++++++++++++++ src/box/execute.c | 270 +---------------------------------------- src/box/execute.h | 18 +-- src/box/iproto.cc | 1 + 6 files changed, 381 insertions(+), 286 deletions(-) create mode 100644 src/box/bind.c create mode 100644 src/box/bind.h diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index 5019127eb..bd3f61261 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -117,6 +117,7 @@ add_library(box STATIC journal.c ck_constraint.c sql.c + bind.c execute.c wal.c call.c diff --git a/src/box/bind.c b/src/box/bind.c new file mode 100644 index 000000000..91bc58087 --- /dev/null +++ b/src/box/bind.c @@ -0,0 +1,239 @@ +/* + * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "bind.h" +#include "errcode.h" +#include "small/region.h" +#include "sql/sqliteInt.h" +#include "sql/sqliteLimit.h" +#include "sql/vdbe.h" + +const char *sql_type_strs[] = { + NULL, + "INTEGER", + "FLOAT", + "TEXT", + "BLOB", + "NULL", +}; + +/** + * Return a string name of a parameter marker. + * @param Bind to get name. + * @retval Zero terminated name. + */ +static inline const char * +sql_bind_name(const struct sql_bind *bind) +{ + if (bind->name) + return tt_sprintf("'%.*s'", bind->name_len, bind->name); + else + return tt_sprintf("%d", (int) bind->pos); +} + +int +sql_bind_decode(struct sql_bind *bind, int i, const char **packet) +{ + bind->pos = i + 1; + if (mp_typeof(**packet) == MP_MAP) { + uint32_t len = mp_decode_map(packet); + /* + * A named parameter is an MP_MAP with + * one key - {'name': value}. + * Report parse error otherwise. + */ + if (len != 1 || mp_typeof(**packet) != MP_STR) { + diag_set(ClientError, ER_INVALID_MSGPACK, + "SQL bind parameter"); + return -1; + } + bind->name = mp_decode_str(packet, &bind->name_len); + } else { + bind->name = NULL; + bind->name_len = 0; + } + switch (mp_typeof(**packet)) { + case MP_UINT: { + uint64_t n = mp_decode_uint(packet); + if (n > INT64_MAX) { + diag_set(ClientError, ER_SQL_BIND_VALUE, + sql_bind_name(bind), "INTEGER"); + return -1; + } + bind->i64 = (int64_t) n; + bind->type = SQLITE_INTEGER; + bind->bytes = sizeof(bind->i64); + break; + } + case MP_INT: + bind->i64 = mp_decode_int(packet); + bind->type = SQLITE_INTEGER; + bind->bytes = sizeof(bind->i64); + break; + case MP_STR: + bind->s = mp_decode_str(packet, &bind->bytes); + bind->type = SQLITE_TEXT; + break; + case MP_DOUBLE: + bind->d = mp_decode_double(packet); + bind->type = SQLITE_FLOAT; + bind->bytes = sizeof(bind->d); + break; + case MP_FLOAT: + bind->d = mp_decode_float(packet); + bind->type = SQLITE_FLOAT; + bind->bytes = sizeof(bind->d); + break; + case MP_NIL: + mp_decode_nil(packet); + bind->type = SQLITE_NULL; + bind->bytes = 1; + break; + case MP_BOOL: + /* SQLite doesn't support boolean. Use int instead. */ + bind->i64 = mp_decode_bool(packet) ? 1 : 0; + bind->type = SQLITE_INTEGER; + bind->bytes = sizeof(bind->i64); + break; + case MP_BIN: + bind->s = mp_decode_bin(packet, &bind->bytes); + bind->type = SQLITE_BLOB; + break; + case MP_EXT: + bind->s = *packet; + mp_next(packet); + bind->bytes = *packet - bind->s; + bind->type = SQLITE_BLOB; + break; + case MP_ARRAY: + diag_set(ClientError, ER_SQL_BIND_TYPE, "ARRAY", + sql_bind_name(bind)); + return -1; + case MP_MAP: + diag_set(ClientError, ER_SQL_BIND_TYPE, "MAP", + sql_bind_name(bind)); + return -1; + default: + unreachable(); + } + return 0; +} + +int +sql_bind_list_decode(const char *data, struct sql_bind **out_bind) +{ + assert(data != NULL); + if (mp_typeof(*data) != MP_ARRAY) { + diag_set(ClientError, ER_INVALID_MSGPACK, "SQL parameter list"); + return -1; + } + uint32_t bind_count = mp_decode_array(&data); + if (bind_count == 0) + return 0; + if (bind_count > SQL_BIND_PARAMETER_MAX) { + diag_set(ClientError, ER_SQL_BIND_PARAMETER_MAX, + (int) bind_count); + return -1; + } + struct region *region = &fiber()->gc; + uint32_t used = region_used(region); + size_t size = sizeof(struct sql_bind) * bind_count; + struct sql_bind *bind = (struct sql_bind *) region_alloc(region, size); + if (bind == NULL) { + diag_set(OutOfMemory, size, "region_alloc", "struct sql_bind"); + return -1; + } + for (uint32_t i = 0; i < bind_count; ++i) { + if (sql_bind_decode(&bind[i], i, &data) != 0) { + region_truncate(region, used); + return -1; + } + } + *out_bind = bind; + return bind_count; +} + +int +sql_bind_column(struct sqlite3_stmt *stmt, const struct sql_bind *p, + uint32_t pos) +{ + int rc; + if (p->name != NULL) { + pos = sqlite3_bind_parameter_lindex(stmt, p->name, p->name_len); + if (pos == 0) { + diag_set(ClientError, ER_SQL_BIND_NOT_FOUND, + sql_bind_name(p)); + return -1; + } + } + switch (p->type) { + case SQLITE_INTEGER: + rc = sqlite3_bind_int64(stmt, pos, p->i64); + break; + case SQLITE_FLOAT: + rc = sqlite3_bind_double(stmt, pos, p->d); + break; + case SQLITE_TEXT: + /* + * Parameters are allocated within message pack, + * received from the iproto thread. IProto thread + * now is waiting for the response and it will not + * free the packet until sqlite3_finalize. So + * there is no need to copy the packet and we can + * use SQLITE_STATIC. + */ + rc = sqlite3_bind_text64(stmt, pos, p->s, p->bytes, + SQLITE_STATIC); + break; + case SQLITE_NULL: + rc = sqlite3_bind_null(stmt, pos); + break; + case SQLITE_BLOB: + rc = sqlite3_bind_blob64(stmt, pos, (const void *) p->s, + p->bytes, SQLITE_STATIC); + break; + default: + unreachable(); + } + if (rc == SQLITE_OK) + return 0; + + switch (rc) { + case SQLITE_NOMEM: + diag_set(OutOfMemory, p->bytes, "vdbe", "bind value"); + break; + case SQLITE_TOOBIG: + default: + diag_set(ClientError, ER_SQL_BIND_VALUE, sql_bind_name(p), + sql_type_strs[p->type]); + break; + } + return -1; +} diff --git a/src/box/bind.h b/src/box/bind.h new file mode 100644 index 000000000..92e7d23a3 --- /dev/null +++ b/src/box/bind.h @@ -0,0 +1,138 @@ +#ifndef TARANTOOL_SQL_BIND_H_INCLUDED +#define TARANTOOL_SQL_BIND_H_INCLUDED +/* + * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> + +struct sqlite3_stmt; + +/** + * Name and value of an SQL prepared statement parameter. + * @todo: merge with sqlite3_value. + */ +struct sql_bind { + /** Bind name. NULL for ordinal binds. */ + const char *name; + /** Length of the @name. */ + uint32_t name_len; + /** Ordinal position of the bind, for ordinal binds. */ + uint32_t pos; + + /** Byte length of the value. */ + uint32_t bytes; + /** SQL type of the value. */ + uint8_t type; + /** Bind value. */ + union { + double d; + int64_t i64; + /** For string or blob. */ + const char *s; + }; +}; + +/** + * Parse MessagePack array of SQL parameters. + * @param data MessagePack array of parameters. Each parameter + * either must have scalar type, or must be a map with the + * following format: {name: value}. Name - string name of + * the named parameter, value - scalar value of the + * parameter. Named and positioned parameters can be mixed. + * For more details + * @sa https://www.sqlite.org/lang_expr.html#varparam. + * @param[out] out_bind Pointer to save decoded parameters. + * + * @retval >= 0 Number of decoded parameters. + * @retval -1 Client or memory error. + */ +int +sql_bind_list_decode(const char *data, struct sql_bind **out_bind); + +/** + * Decode a single bind column from the binary protocol packet. + * @param[out] bind Bind to decode to. + * @param i Ordinal bind number. + * @param packet MessagePack encoded parameter value. Either + * scalar or map: {string_name: scalar_value}. + * + * @retval 0 Success. + * @retval -1 Memory or client error. + */ +int +sql_bind_decode(struct sql_bind *bind, int i, const char **packet); + +/** + * Bind SQL parameter value to its position. + * @param stmt Prepared statement. + * @param p Parameter value. + * @param pos Ordinal bind position. + * + * @retval 0 Success. + * @retval -1 SQL error. + */ +int +sql_bind_column(struct sqlite3_stmt *stmt, const struct sql_bind *p, + uint32_t pos); + +/** + * Bind parameter values to the prepared statement. + * @param stmt Prepared statement. + * @param bind Parameters to bind. + * @param bind_count Length of @a bind. + * + * @retval 0 Success. + * @retval -1 Client or memory error. + */ +static inline int +sql_bind(struct sqlite3_stmt *stmt, const struct sql_bind *bind, + uint32_t bind_count) +{ + assert(stmt != NULL); + uint32_t pos = 1; + for (uint32_t i = 0; i < bind_count; pos = ++i + 1) { + if (sql_bind_column(stmt, &bind[i], pos) != 0) + return -1; + } + return 0; +} + +#if defined(__cplusplus) +} /* extern "C" { */ +#endif + +#endif /* TARANTOOL_SQL_BIND_H_INCLUDED */ diff --git a/src/box/execute.c b/src/box/execute.c index 38b6cbc88..b8c7087a7 100644 --- a/src/box/execute.c +++ b/src/box/execute.c @@ -30,6 +30,7 @@ */ #include "execute.h" +#include "bind.h" #include "iproto_constants.h" #include "sql/sqliteInt.h" #include "sql/sqliteLimit.h" @@ -44,190 +45,10 @@ #include "tuple.h" #include "sql/vdbe.h" -const char *sql_type_strs[] = { - NULL, - "INTEGER", - "FLOAT", - "TEXT", - "BLOB", - "NULL", -}; - const char *sql_info_key_strs[] = { "row count", }; -/** - * Name and value of an SQL prepared statement parameter. - * @todo: merge with sqlite3_value. - */ -struct sql_bind { - /** Bind name. NULL for ordinal binds. */ - const char *name; - /** Length of the @name. */ - uint32_t name_len; - /** Ordinal position of the bind, for ordinal binds. */ - uint32_t pos; - - /** Byte length of the value. */ - uint32_t bytes; - /** SQL type of the value. */ - uint8_t type; - /** Bind value. */ - union { - double d; - int64_t i64; - /** For string or blob. */ - const char *s; - }; -}; - -/** - * Return a string name of a parameter marker. - * @param Bind to get name. - * @retval Zero terminated name. - */ -static inline const char * -sql_bind_name(const struct sql_bind *bind) -{ - if (bind->name) - return tt_sprintf("'%.*s'", bind->name_len, bind->name); - else - return tt_sprintf("%d", (int) bind->pos); -} - -/** - * Decode a single bind column from the binary protocol packet. - * @param[out] bind Bind to decode to. - * @param i Ordinal bind number. - * @param packet MessagePack encoded parameter value. Either - * scalar or map: {string_name: scalar_value}. - * - * @retval 0 Success. - * @retval -1 Memory or client error. - */ -static inline int -sql_bind_decode(struct sql_bind *bind, int i, const char **packet) -{ - bind->pos = i + 1; - if (mp_typeof(**packet) == MP_MAP) { - uint32_t len = mp_decode_map(packet); - /* - * A named parameter is an MP_MAP with - * one key - {'name': value}. - * Report parse error otherwise. - */ - if (len != 1 || mp_typeof(**packet) != MP_STR) { - diag_set(ClientError, ER_INVALID_MSGPACK, - "SQL bind parameter"); - return -1; - } - bind->name = mp_decode_str(packet, &bind->name_len); - } else { - bind->name = NULL; - bind->name_len = 0; - } - switch (mp_typeof(**packet)) { - case MP_UINT: { - uint64_t n = mp_decode_uint(packet); - if (n > INT64_MAX) { - diag_set(ClientError, ER_SQL_BIND_VALUE, - sql_bind_name(bind), "INTEGER"); - return -1; - } - bind->i64 = (int64_t) n; - bind->type = SQLITE_INTEGER; - bind->bytes = sizeof(bind->i64); - break; - } - case MP_INT: - bind->i64 = mp_decode_int(packet); - bind->type = SQLITE_INTEGER; - bind->bytes = sizeof(bind->i64); - break; - case MP_STR: - bind->s = mp_decode_str(packet, &bind->bytes); - bind->type = SQLITE_TEXT; - break; - case MP_DOUBLE: - bind->d = mp_decode_double(packet); - bind->type = SQLITE_FLOAT; - bind->bytes = sizeof(bind->d); - break; - case MP_FLOAT: - bind->d = mp_decode_float(packet); - bind->type = SQLITE_FLOAT; - bind->bytes = sizeof(bind->d); - break; - case MP_NIL: - mp_decode_nil(packet); - bind->type = SQLITE_NULL; - bind->bytes = 1; - break; - case MP_BOOL: - /* SQLite doesn't support boolean. Use int instead. */ - bind->i64 = mp_decode_bool(packet) ? 1 : 0; - bind->type = SQLITE_INTEGER; - bind->bytes = sizeof(bind->i64); - break; - case MP_BIN: - bind->s = mp_decode_bin(packet, &bind->bytes); - bind->type = SQLITE_BLOB; - break; - case MP_EXT: - bind->s = *packet; - mp_next(packet); - bind->bytes = *packet - bind->s; - bind->type = SQLITE_BLOB; - break; - case MP_ARRAY: - diag_set(ClientError, ER_SQL_BIND_TYPE, "ARRAY", - sql_bind_name(bind)); - return -1; - case MP_MAP: - diag_set(ClientError, ER_SQL_BIND_TYPE, "MAP", - sql_bind_name(bind)); - return -1; - default: - unreachable(); - } - return 0; -} - -int -sql_bind_list_decode(const char *data, struct sql_bind **out_bind) -{ - assert(data != NULL); - if (mp_typeof(*data) != MP_ARRAY) { - diag_set(ClientError, ER_INVALID_MSGPACK, "SQL parameter list"); - return -1; - } - uint32_t bind_count = mp_decode_array(&data); - if (bind_count == 0) - return 0; - if (bind_count > SQL_BIND_PARAMETER_MAX) { - diag_set(ClientError, ER_SQL_BIND_PARAMETER_MAX, - (int) bind_count); - return -1; - } - struct region *region = &fiber()->gc; - uint32_t used = region_used(region); - size_t size = sizeof(struct sql_bind) * bind_count; - struct sql_bind *bind = (struct sql_bind *) region_alloc(region, size); - if (bind == NULL) { - diag_set(OutOfMemory, size, "region_alloc", "struct sql_bind"); - return -1; - } - for (uint32_t i = 0; i < bind_count; ++i) { - if (sql_bind_decode(&bind[i], i, &data) != 0) { - region_truncate(region, used); - return -1; - } - } - *out_bind = bind; - return bind_count; -} - /** * Serialize a single column of a result set row. * @param stmt Prepared and started statement. At least one @@ -363,95 +184,6 @@ error: return -1; } -/** - * Bind SQL parameter value to its position. - * @param stmt Prepared statement. - * @param p Parameter value. - * @param pos Ordinal bind position. - * - * @retval 0 Success. - * @retval -1 SQL error. - */ -static inline int -sql_bind_column(struct sqlite3_stmt *stmt, const struct sql_bind *p, - uint32_t pos) -{ - int rc; - if (p->name != NULL) { - pos = sqlite3_bind_parameter_lindex(stmt, p->name, p->name_len); - if (pos == 0) { - diag_set(ClientError, ER_SQL_BIND_NOT_FOUND, - sql_bind_name(p)); - return -1; - } - } - switch (p->type) { - case SQLITE_INTEGER: - rc = sqlite3_bind_int64(stmt, pos, p->i64); - break; - case SQLITE_FLOAT: - rc = sqlite3_bind_double(stmt, pos, p->d); - break; - case SQLITE_TEXT: - /* - * Parameters are allocated within message pack, - * received from the iproto thread. IProto thread - * now is waiting for the response and it will not - * free the packet until sqlite3_finalize. So - * there is no need to copy the packet and we can - * use SQLITE_STATIC. - */ - rc = sqlite3_bind_text64(stmt, pos, p->s, p->bytes, - SQLITE_STATIC); - break; - case SQLITE_NULL: - rc = sqlite3_bind_null(stmt, pos); - break; - case SQLITE_BLOB: - rc = sqlite3_bind_blob64(stmt, pos, (const void *) p->s, - p->bytes, SQLITE_STATIC); - break; - default: - unreachable(); - } - if (rc == SQLITE_OK) - return 0; - - switch (rc) { - case SQLITE_NOMEM: - diag_set(OutOfMemory, p->bytes, "vdbe", "bind value"); - break; - case SQLITE_TOOBIG: - default: - diag_set(ClientError, ER_SQL_BIND_VALUE, sql_bind_name(p), - sql_type_strs[p->type]); - break; - } - return -1; -} - -/** - * Bind parameter values to the prepared statement. - * @param stmt Prepared statement. - * @param bind Parameters to bind. - * @param bind_count Length of @a bind. - * - * @retval 0 Success. - * @retval -1 Client or memory error. - */ -static inline int -sql_bind(struct sqlite3_stmt *stmt, const struct sql_bind *bind, - uint32_t bind_count) -{ - assert(stmt != NULL); - uint32_t pos = 1; - for (uint32_t i = 0; i < bind_count; pos = ++i + 1) { - if (sql_bind_column(stmt, &bind[i], pos) != 0) - return -1; - } - return 0; -} - /** * Serialize a description of the prepared statement. * @param stmt Prepared statement. diff --git a/src/box/execute.h b/src/box/execute.h index 60b8f319b..d30d5c2d1 100644 --- a/src/box/execute.h +++ b/src/box/execute.h @@ -51,6 +51,7 @@ extern const char *sql_info_key_strs[]; struct obuf; struct region; struct sql_bind; +struct sqlite3_stmt; /** Response on EXECUTE request. */ struct sql_response { @@ -60,23 +61,6 @@ struct sql_response { void *prep_stmt; }; -/** - * Parse MessagePack array of SQL parameters. - * @param data MessagePack array of parameters. Each parameter - * either must have scalar type, or must be a map with the - * following format: {name: value}. Name - string name of - * the named parameter, value - scalar value of the - * parameter. Named and positioned parameters can be mixed. - * For more details - * @sa https://www.sqlite.org/lang_expr.html#varparam. - * @param[out] out_bind Pointer to save decoded parameters. - * - * @retval >= 0 Number of decoded parameters. - * @retval -1 Client or memory error. - */ -int -sql_bind_list_decode(const char *data, struct sql_bind **out_bind); - /** * Dump a built response into @an out buffer. The response is * destroyed. diff --git a/src/box/iproto.cc b/src/box/iproto.cc index a08c8c5cb..63fd4c401 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -49,6 +49,7 @@ #include "memory.h" #include "random.h" +#include "bind.h" #include "port.h" #include "box.h" #include "call.h" -- 2.19.2
next prev parent reply other threads:[~2019-01-30 8:59 UTC|newest] Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-01-30 8:59 [tarantool-patches] [PATCH v2 0/9] sql: Checks on server side Kirill Shcherbatov 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 1/9] box: fix upgrade script for _fk_constraint space Kirill Shcherbatov 2019-03-11 18:44 ` [tarantool-patches] " n.pettik 2019-03-13 11:36 ` Kirill Yukhin 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 2/9] box: fix _trigger and _ck_constraint access check Kirill Shcherbatov 2019-03-11 19:29 ` [tarantool-patches] " n.pettik 2019-03-22 9:29 ` Vladislav Shpilevoy 2019-03-26 10:59 ` Kirill Shcherbatov 2019-04-01 14:06 ` n.pettik 2019-03-13 11:38 ` Kirill Yukhin 2019-03-13 11:44 ` Kirill Yukhin 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 3/9] box: fix Tarantool upgrade from 2.1.0 to 2.1.1 Kirill Shcherbatov 2019-03-12 11:45 ` [tarantool-patches] " n.pettik 2019-03-20 15:12 ` n.pettik 2019-03-20 15:38 ` Kirill Shcherbatov 2019-03-21 15:23 ` n.pettik 2019-03-21 15:36 ` Vladislav Shpilevoy 2019-03-22 9:28 ` Vladislav Shpilevoy 2019-03-22 10:18 ` Kirill Shcherbatov 2019-03-22 10:21 ` Vladislav Shpilevoy 2019-03-26 9:52 ` Kirill Yukhin 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 4/9] box: fix on_replace_trigger_rollback routine Kirill Shcherbatov 2019-03-11 20:00 ` [tarantool-patches] " n.pettik 2019-03-13 11:39 ` Kirill Yukhin 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 5/9] schema: add new system space for CHECK constraints Kirill Shcherbatov 2019-03-22 9:29 ` [tarantool-patches] " Vladislav Shpilevoy 2019-03-22 9:52 ` n.pettik 2019-03-26 10:59 ` Kirill Shcherbatov 2019-04-01 19:45 ` n.pettik 2019-04-16 13:51 ` Kirill Shcherbatov 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 6/9] sql: disallow use of TYPEOF in Check Kirill Shcherbatov 2019-03-26 10:59 ` [tarantool-patches] " Kirill Shcherbatov 2019-04-01 19:52 ` n.pettik 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 7/9] sql: refactor sqlite3_reset routine Kirill Shcherbatov 2019-03-26 10:59 ` [tarantool-patches] " Kirill Shcherbatov 2019-01-30 8:59 ` Kirill Shcherbatov [this message] 2019-03-26 10:59 ` [tarantool-patches] Re: [PATCH v2 8/9] box: exported sql_bind structure and API Kirill Shcherbatov 2019-01-30 8:59 ` [tarantool-patches] [PATCH v2 9/9] sql: run check constraint tests on space alter Kirill Shcherbatov 2019-03-26 10:59 ` [tarantool-patches] " Kirill Shcherbatov 2019-04-02 14:14 ` n.pettik 2019-04-16 13:51 ` Kirill Shcherbatov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1c364cb9d4584a5c7d1375a121f794a680efbc3f.1548838034.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH v2 8/9] box: exported sql_bind structure and API' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox