From: Nikita Pettik <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Nikita Pettik <korablev@tarantool.org> Subject: [tarantool-patches] [PATCH 4/6] sql: make built-in functions operate on unsigned values Date: Fri, 7 Jun 2019 18:37:44 +0300 [thread overview] Message-ID: <4acf9fab112e7ca119f1b2bf5efea53b3831ea4f.1559919361.git.korablev@tarantool.org> (raw) In-Reply-To: <cover.1559919361.git.korablev@tarantool.org> In-Reply-To: <cover.1559919361.git.korablev@tarantool.org> As a part of introduction unsigned type in SQL, let's patch all built-in function to make them accept and operate on unsigned value, i.e. values which come with MEM_UInt VDBE memory type. Part of #3810 Part of #4015 --- src/box/sql/func.c | 70 ++++++++++++++++++------------------------- src/box/sql/main.c | 3 +- src/box/sql/sqlInt.h | 9 ++++-- src/box/sql/vdbeInt.h | 2 +- src/box/sql/vdbeapi.c | 22 ++++++++++---- test/sql-tap/cast.test.lua | 8 ++--- test/sql-tap/check.test.lua | 2 +- test/sql-tap/cse.test.lua | 6 ++-- test/sql-tap/default.test.lua | 2 +- test/sql-tap/fkey2.test.lua | 4 +-- test/sql-tap/func.test.lua | 18 ++++++++--- test/sql-tap/table.test.lua | 2 +- test/sql-tap/tkt3493.test.lua | 4 +-- 13 files changed, 82 insertions(+), 70 deletions(-) diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 457c9b92b..365f8f9d2 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -111,9 +111,11 @@ typeofFunc(sql_context * context, int NotUsed, sql_value ** argv) UNUSED_PARAMETER(NotUsed); switch (sql_value_type(argv[0])) { case MP_INT: - case MP_UINT: z = "integer"; break; + case MP_UINT: + z = "unsigned"; + break; case MP_STR: z = "string"; break; @@ -148,8 +150,7 @@ lengthFunc(sql_context * context, int argc, sql_value ** argv) case MP_INT: case MP_UINT: case MP_DOUBLE:{ - sql_result_int(context, - sql_value_bytes(argv[0])); + sql_result_uint(context, sql_value_bytes(argv[0])); break; } case MP_STR:{ @@ -157,7 +158,7 @@ lengthFunc(sql_context * context, int argc, sql_value ** argv) if (z == 0) return; len = sql_utf8_char_count(z, sql_value_bytes(argv[0])); - sql_result_int(context, len); + sql_result_uint(context, len); break; } default:{ @@ -179,24 +180,15 @@ absFunc(sql_context * context, int argc, sql_value ** argv) assert(argc == 1); UNUSED_PARAMETER(argc); switch (sql_value_type(argv[0])) { - case MP_UINT: + case MP_UINT: { + sql_result_uint(context, sql_value_uint64(argv[0])); + break; + } case MP_INT:{ - i64 iVal = sql_value_int64(argv[0]); - if (iVal < 0) { - if (iVal == SMALLEST_INT64) { - /* IMP: R-31676-45509 If X is the integer -9223372036854775808 - * then abs(X) throws an integer overflow error since there is no - * equivalent positive 64-bit two complement value. - */ - sql_result_error(context, - "integer overflow", - -1); - return; - } - iVal = -iVal; - } - sql_result_int64(context, iVal); - break; + i64 iVal = sql_value_int64(argv[0]); + assert(iVal < 0); + sql_result_uint(context, -iVal); + break; } case MP_NIL:{ /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ @@ -358,7 +350,8 @@ position_func(struct sql_context *context, int argc, struct Mem **argv) } } finish: - sql_result_int(context, position); + assert(position >= 0); + sql_result_uint(context, position); } /* @@ -645,21 +638,13 @@ ICU_CASE_CONVERT(Upper); static void randomFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2) { - sql_int64 r; + int64_t r; UNUSED_PARAMETER2(NotUsed, NotUsed2); sql_randomness(sizeof(r), &r); - if (r < 0) { - /* We need to prevent a random number of 0x8000000000000000 - * (or -9223372036854775808) since when you do abs() of that - * number of you get the same value back again. To do this - * in a way that is testable, mask the sign bit off of negative - * values, resulting in a positive value. Then take the - * 2s complement of that positive value. The end result can - * therefore be no less than -9223372036854775807. - */ - r = -(r & LARGEST_INT64); - } - sql_result_int64(context, r); + if (r < 0) + sql_result_int(context, r); + else + sql_result_uint(context, r); } /* @@ -1126,7 +1111,7 @@ unicodeFunc(sql_context * context, int argc, sql_value ** argv) const unsigned char *z = sql_value_text(argv[0]); (void)argc; if (z && z[0]) - sql_result_int(context, sqlUtf8Read(&z)); + sql_result_uint(context, sqlUtf8Read(&z)); } /* @@ -1145,10 +1130,13 @@ charFunc(sql_context * context, int argc, sql_value ** argv) return; } for (i = 0; i < argc; i++) { - sql_int64 x; + uint64_t x; unsigned c; - x = sql_value_int64(argv[i]); - if (x < 0 || x > 0x10ffff) + if (sql_value_type(argv[i]) == MP_INT) + x = 0xfffd; + else + x = sql_value_uint64(argv[i]); + if (x > 0x10ffff) x = 0xfffd; c = (unsigned)(x & 0x1fffff); if (c < 0x00080) { @@ -1627,7 +1615,7 @@ sum_step(struct sql_context *context, int argc, sql_value **argv) else p->rSum += (uint64_t) v; if ((p->approx | p->overflow) == 0 && - sql_add_int(p->iSum, p->is_neg, v, v < 0, &p->iSum, + sql_add_int(p->iSum, p->is_neg, v, type == MP_INT, &p->iSum, &p->is_neg) != 0) { p->overflow = 1; } @@ -1698,7 +1686,7 @@ countFinalize(sql_context * context) { CountCtx *p; p = sql_aggregate_context(context, 0); - sql_result_int64(context, p ? p->n : 0); + sql_result_uint(context, p ? p->n : 0); } /* diff --git a/src/box/sql/main.c b/src/box/sql/main.c index fe1135a71..6a08a9302 100644 --- a/src/box/sql/main.c +++ b/src/box/sql/main.c @@ -250,7 +250,8 @@ sql_row_count(struct sql_context *context, MAYBE_UNUSED int unused1, MAYBE_UNUSED sql_value **unused2) { sql *db = sql_context_db_handle(context); - sql_result_int(context, db->nChange); + assert(db->nChange >= 0); + sql_result_uint(context, db->nChange); } /* diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index c0e2ab699..4697e3003 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -455,6 +455,9 @@ sql_column_subtype(struct sql_stmt *stmt, int i); sql_int64 sql_value_int64(sql_value *); +uint64_t +sql_value_uint64(sql_value *val); + const unsigned char * sql_value_text(sql_value *); @@ -496,13 +499,13 @@ void sql_result_error_code(sql_context *, int); void -sql_result_int(sql_context *, int); +sql_result_int(sql_context *, int64_t); void -sql_result_bool(struct sql_context *ctx, bool value); +sql_result_uint(sql_context *ctx, int64_t u_val); void -sql_result_int64(sql_context *, sql_int64); +sql_result_bool(struct sql_context *ctx, bool value); void sql_result_null(sql_context *); diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h index abed46486..0c86ed0f3 100644 --- a/src/box/sql/vdbeInt.h +++ b/src/box/sql/vdbeInt.h @@ -501,7 +501,7 @@ void sqlVdbeMemShallowCopy(Mem *, const Mem *, int); void sqlVdbeMemMove(Mem *, Mem *); int sqlVdbeMemNulTerminate(Mem *); int sqlVdbeMemSetStr(Mem *, const char *, int, u8, void (*)(void *)); -void sqlVdbeMemSetInt64(Mem *, i64); +void sqlVdbeMemSetInt64(Mem *, i64, bool is_neg); void mem_set_bool(struct Mem *mem, bool value); diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 393782c23..752efeecb 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -239,6 +239,16 @@ sql_value_int64(sql_value * pVal) return i; } +uint64_t +sql_value_uint64(sql_value *val) +{ + int64_t i = 0; + bool is_neg; + sqlVdbeIntValue((struct Mem *) val, &i, &is_neg); + assert(!is_neg); + return i; +} + enum sql_subtype sql_value_subtype(sql_value * pVal) { @@ -386,21 +396,21 @@ sql_result_error(sql_context * pCtx, const char *z, int n) } void -sql_result_int(sql_context * pCtx, int iVal) +sql_result_int(sql_context * pCtx, int64_t iVal) { - mem_set_int(pCtx->pOut, (i64) iVal, iVal < 0); + mem_set_int(pCtx->pOut, (i64) iVal, true); } void -sql_result_bool(struct sql_context *ctx, bool value) +sql_result_uint(sql_context *ctx, int64_t u_val) { - mem_set_bool(ctx->pOut, value); + mem_set_int(ctx->pOut, u_val, false); } void -sql_result_int64(sql_context * pCtx, i64 iVal) +sql_result_bool(struct sql_context *ctx, bool value) { - mem_set_int(pCtx->pOut, iVal, iVal < 0); + mem_set_bool(ctx->pOut, value); } void diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua index 531c310d2..315f49d08 100755 --- a/test/sql-tap/cast.test.lua +++ b/test/sql-tap/cast.test.lua @@ -220,7 +220,7 @@ test:do_execsql_test( SELECT typeof(123) ]], { -- <cast-1.22> - "integer" + "unsigned" -- </cast-1.22> }) @@ -280,7 +280,7 @@ test:do_execsql_test( SELECT typeof(CAST(123 AS SCALAR)) ]], { -- <cast-1.28> - "integer" + "unsigned" -- </cast-1.28> }) @@ -300,7 +300,7 @@ test:do_execsql_test( SELECT typeof(CAST(123 AS integer)) ]], { -- <cast-1.30> - "integer" + "unsigned" -- </cast-1.30> }) @@ -400,7 +400,7 @@ test:do_execsql_test( SELECT typeof(CAST(123.456 AS integer)) ]], { -- <cast-1.38> - "integer" + "unsigned" -- </cast-1.38> }) diff --git a/test/sql-tap/check.test.lua b/test/sql-tap/check.test.lua index b01afca7c..8fd722924 100755 --- a/test/sql-tap/check.test.lua +++ b/test/sql-tap/check.test.lua @@ -206,7 +206,7 @@ test:do_execsql_test( [[ CREATE TABLE t2( id INT primary key, - x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=='integer'), + x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=='unsigned'), y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='number' ), z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='string' ) ); diff --git a/test/sql-tap/cse.test.lua b/test/sql-tap/cse.test.lua index 78d0d2046..f83cde9bd 100755 --- a/test/sql-tap/cse.test.lua +++ b/test/sql-tap/cse.test.lua @@ -165,7 +165,7 @@ test:do_execsql_test( SELECT CAST(b AS integer), typeof(b), CAST(b AS text), typeof(b) FROM t1 ]], { -- <cse-1.10> - 11, "integer", "11", "integer", 21, "integer", "21", "integer" + 11, "unsigned", "11", "unsigned", 21, "unsigned", "21", "unsigned" -- </cse-1.10> }) @@ -201,7 +201,7 @@ test:do_execsql_test( SELECT upper(b), typeof(b), b FROM t1 ]], { -- <cse-1.13> - "11", "integer", 11, "21", "integer", 21 + "11", "unsigned", 11, "21", "unsigned", 21 -- </cse-1.13> }) @@ -211,7 +211,7 @@ test:do_execsql_test( SELECT b, typeof(b), upper(b), typeof(b), b FROM t1 ]], { -- <cse-1.14> - 11, "integer", "11", "integer", 11, 21, "integer", "21", "integer", 21 + 11, "unsigned", "11", "unsigned", 11, 21, "unsigned", "21", "unsigned", 21 -- </cse-1.14> }) diff --git a/test/sql-tap/default.test.lua b/test/sql-tap/default.test.lua index 55d16bcd7..0353796d5 100755 --- a/test/sql-tap/default.test.lua +++ b/test/sql-tap/default.test.lua @@ -119,7 +119,7 @@ test:do_execsql_test( -- In current situation I don't know what to do, need Kirill's -- advice. -- Bulat - 1, "integer", 5, "integer", "row1", "string", 5.25, "number", 8.67, "number", "321", "string", 432, "integer" + 1, "unsigned", 5, "unsigned", "row1", "string", 5.25, "number", 8.67, "number", "321", "string", 432, "unsigned" -- </default-3.1> }) diff --git a/test/sql-tap/fkey2.test.lua b/test/sql-tap/fkey2.test.lua index 54e5059b3..8e786edec 100755 --- a/test/sql-tap/fkey2.test.lua +++ b/test/sql-tap/fkey2.test.lua @@ -320,10 +320,10 @@ test:do_execsql_test( CREATE TABLE j(j INT PRIMARY KEY REFERENCES i); INSERT INTO i VALUES(35); INSERT INTO j VALUES(35); - SELECT j, typeof(j) FROM j; + SELECT j FROM j; ]], { -- <fkey2-2.1> - 35, "integer" + 35 -- </fkey2-2.1> }) diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua index 314c528ab..9cf9c2f67 100755 --- a/test/sql-tap/func.test.lua +++ b/test/sql-tap/func.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool test = require("sqltester") -test:plan(14591) +test:plan(14592) --!./tcltestrunner.lua -- 2001 September 15 @@ -908,7 +908,7 @@ test:do_execsql_test( UNION ALL SELECT -9223372036854775807) ]], { -- <func-8.6> - "integer" + "unsigned" -- </func-8.6> }) @@ -1587,7 +1587,7 @@ test:do_execsql_test( SELECT typeof(sum(x)) FROM t6 ]], { -- <func-18.11> - "integer" + "unsigned" -- </func-18.11> }) @@ -1742,10 +1742,20 @@ test:do_catchsql_test( SELECT abs(-9223372036854775807-1); ]], { -- <func-18.32> - 1, "Failed to execute SQL statement: integer overflow" + 0, {9223372036854775808LL} -- </func-18.32> }) +test:do_catchsql_test( + "func-18.33", + [[ + SELECT abs(-9223372036854775807-1); + ]], { + -- <func-18.32> + 0, {9223372036854775808LL} + -- </func-18.32> +}) + -- The MATCH function exists but is only a stub and always throws an error. -- test:do_execsql_test( diff --git a/test/sql-tap/table.test.lua b/test/sql-tap/table.test.lua index 5b793c0fc..5ed4a83fa 100755 --- a/test/sql-tap/table.test.lua +++ b/test/sql-tap/table.test.lua @@ -906,7 +906,7 @@ test:do_execsql_test( FROM t7 LIMIT 1; ]], { -- <table-11.1> - "integer", "null", "null", "null", "null", "null", "null", "null" + "unsigned", "null", "null", "null", "null", "null", "null", "null" -- </table-11.1> }) diff --git a/test/sql-tap/tkt3493.test.lua b/test/sql-tap/tkt3493.test.lua index 67e79da72..df6bb4d36 100755 --- a/test/sql-tap/tkt3493.test.lua +++ b/test/sql-tap/tkt3493.test.lua @@ -229,7 +229,7 @@ test:do_execsql_test( SELECT typeof(b), b FROM t1 GROUP BY a HAVING b='456' ]], { -- <tkt3493-2.5.1> - "integer", 456 + "unsigned", 456 -- </tkt3493-2.5.1> }) @@ -239,7 +239,7 @@ test:do_execsql_test( SELECT typeof(b), b FROM t1 GROUP BY b HAVING b='456' ]], { -- <tkt3493-2.5.2> - "integer", 456 + "unsigned", 456 -- </tkt3493-2.5.2> }) -- 2.15.1
next prev parent reply other threads:[~2019-06-07 15:37 UTC|newest] Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-06-07 15:37 [tarantool-patches] [PATCH 0/6] Introduce UNSIGNED type in SQL Nikita Pettik 2019-06-07 15:37 ` [tarantool-patches] [PATCH 1/6] sql: refactor sql_atoi64() Nikita Pettik 2019-06-11 21:11 ` [tarantool-patches] " Vladislav Shpilevoy 2019-07-01 14:20 ` n.pettik 2019-07-01 21:53 ` Vladislav Shpilevoy 2019-07-05 16:32 ` n.pettik 2019-06-07 15:37 ` [tarantool-patches] [PATCH 2/6] sql: separate VDBE memory holding positive and negative ints Nikita Pettik 2019-06-11 21:11 ` [tarantool-patches] " Vladislav Shpilevoy 2019-07-01 14:21 ` n.pettik 2019-07-01 21:53 ` Vladislav Shpilevoy 2019-07-05 16:33 ` n.pettik 2019-06-07 15:37 ` [tarantool-patches] [PATCH 3/6] sql: refactor arithmetic operations to support unsigned ints Nikita Pettik 2019-06-11 21:11 ` [tarantool-patches] " Vladislav Shpilevoy 2019-07-01 14:21 ` n.pettik 2019-07-01 21:53 ` Vladislav Shpilevoy 2019-07-05 16:36 ` n.pettik 2019-07-10 22:49 ` Vladislav Shpilevoy 2019-07-17 12:24 ` n.pettik 2019-06-07 15:37 ` Nikita Pettik [this message] 2019-06-11 21:11 ` [tarantool-patches] Re: [PATCH 4/6] sql: make built-in functions operate on unsigned values Vladislav Shpilevoy 2019-07-01 14:21 ` n.pettik 2019-07-01 21:53 ` Vladislav Shpilevoy 2019-07-05 16:36 ` n.pettik 2019-07-10 22:49 ` Vladislav Shpilevoy 2019-07-17 0:53 ` n.pettik 2019-06-07 15:37 ` [tarantool-patches] [PATCH 5/6] sql: introduce extended range for INTEGER type Nikita Pettik 2019-06-11 21:11 ` [tarantool-patches] " Vladislav Shpilevoy 2019-07-01 14:21 ` n.pettik 2019-07-01 21:53 ` Vladislav Shpilevoy 2019-07-24 15:59 ` Konstantin Osipov 2019-07-24 16:54 ` n.pettik 2019-07-24 17:09 ` Konstantin Osipov 2019-06-07 15:37 ` [tarantool-patches] [PATCH 6/6] sql: allow to specify UNSIGNED column type Nikita Pettik 2019-07-01 21:53 ` [tarantool-patches] " Vladislav Shpilevoy 2019-07-05 16:36 ` n.pettik 2019-07-10 22:49 ` Vladislav Shpilevoy 2019-07-11 21:25 ` Vladislav Shpilevoy 2019-07-17 0:53 ` n.pettik 2019-07-18 20:18 ` Vladislav Shpilevoy 2019-07-18 20:56 ` n.pettik 2019-07-18 21:08 ` Vladislav Shpilevoy 2019-07-18 21:13 ` Vladislav Shpilevoy 2019-07-22 10:20 ` n.pettik 2019-07-22 19:17 ` Vladislav Shpilevoy 2019-07-22 10:20 ` n.pettik 2019-07-17 0:54 ` n.pettik 2019-07-18 20:18 ` Vladislav Shpilevoy 2019-08-06 19:36 ` n.pettik 2019-07-24 13:01 ` [tarantool-patches] Re: [PATCH 0/6] Introduce UNSIGNED type in SQL Kirill Yukhin
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=4acf9fab112e7ca119f1b2bf5efea53b3831ea4f.1559919361.git.korablev@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH 4/6] sql: make built-in functions operate on unsigned values' \ /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