Tarantool development patches archive
 help / color / mirror / Atom feed
From: imeevma@tarantool.org
To: korablev@tarantool.org, tsafin@tarantool.org,
	tarantool-patches@dev.tarantool.org
Subject: [Tarantool-patches] [PATCH v6 06/22] sql: check args of length()
Date: Thu, 16 Jul 2020 17:45:52 +0300	[thread overview]
Message-ID: <e8f345be824a3b1f35ad862067b683e0fc695f9b.1594909974.git.imeevma@gmail.com> (raw)
In-Reply-To: <cover.1594909974.git.imeevma@gmail.com>

After this patch, the argument types of the length(), char_length() and
character_length() functions will be checked properly.

Part of #4159
---
 src/box/sql/func.c             |  48 ++++-------
 test/sql-tap/func.test.lua     |   2 +-
 test/sql-tap/func5.test.lua    | 149 ++++++++++++++++++++++++++++++++-
 test/sql-tap/orderby1.test.lua |   2 +-
 test/sql/boolean.result        |  10 +--
 5 files changed, 170 insertions(+), 41 deletions(-)

diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 2d0aea801..a22ba38e2 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -467,30 +467,18 @@ lengthFunc(sql_context * context, int argc, sql_value ** argv)
 
 	assert(argc == 1);
 	UNUSED_PARAMETER(argc);
-	switch (sql_value_type(argv[0])) {
-	case MP_BIN:
-	case MP_ARRAY:
-	case MP_MAP:
-	case MP_INT:
-	case MP_UINT:
-	case MP_BOOL:
-	case MP_DOUBLE:{
-			sql_result_uint(context, sql_value_bytes(argv[0]));
-			break;
-		}
-	case MP_STR:{
-			const unsigned char *z = sql_value_text(argv[0]);
-			if (z == 0)
-				return;
-			len = sql_utf8_char_count(z, sql_value_bytes(argv[0]));
-			sql_result_uint(context, len);
-			break;
-		}
-	default:{
-			sql_result_null(context);
-			break;
-		}
-	}
+	enum mp_type mp_type = sql_value_type(argv[0]);
+	if (mp_type == MP_NIL)
+		return sql_result_null(context);
+	if (mp_type == MP_BIN)
+		return sql_result_uint(context, sql_value_bytes(argv[0]));
+	assert(mp_type == MP_STR);
+	const unsigned char *z = sql_value_text(argv[0]);
+	if (z == NULL)
+		return;
+	len = sql_utf8_char_count(z, sql_value_bytes(argv[0]));
+	sql_result_uint(context, len);
+	return;
 }
 
 /*
@@ -2278,9 +2266,9 @@ static struct {
 	 }, {
 	 .name = "CHARACTER_LENGTH",
 	 .param_count = 1,
-	 .first_arg = FIELD_TYPE_ANY,
+	 .first_arg = FIELD_TYPE_STRING,
 	 .args = FIELD_TYPE_ANY,
-	 .is_blob_like_str = false,
+	 .is_blob_like_str = true,
 	 .returns = FIELD_TYPE_INTEGER,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = true,
@@ -2291,9 +2279,9 @@ static struct {
 	}, {
 	 .name = "CHAR_LENGTH",
 	 .param_count = 1,
-	 .first_arg = FIELD_TYPE_ANY,
+	 .first_arg = FIELD_TYPE_STRING,
 	 .args = FIELD_TYPE_ANY,
-	 .is_blob_like_str = false,
+	 .is_blob_like_str = true,
 	 .returns = FIELD_TYPE_INTEGER,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = true,
@@ -2551,9 +2539,9 @@ static struct {
 	}, {
 	 .name = "LENGTH",
 	 .param_count = 1,
-	 .first_arg = FIELD_TYPE_ANY,
+	 .first_arg = FIELD_TYPE_STRING,
 	 .args = FIELD_TYPE_ANY,
-	 .is_blob_like_str = false,
+	 .is_blob_like_str = true,
 	 .returns = FIELD_TYPE_INTEGER,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = true,
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index ffee8f1c5..69d175e16 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -95,7 +95,7 @@ test:do_execsql_test(
 test:do_execsql_test(
     "func-1.4",
     [[
-        SELECT coalesce(length(a),-1) FROM t2
+        SELECT coalesce(length(CAST(a AS STRING)),-1) FROM t2
     ]], {
         -- <func-1.4>
         1, -1, 3, -1, 5
diff --git a/test/sql-tap/func5.test.lua b/test/sql-tap/func5.test.lua
index 6e65b98ac..0398d8a9d 100755
--- a/test/sql-tap/func5.test.lua
+++ b/test/sql-tap/func5.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(57)
+test:plan(78)
 
 --!./tcltestrunner.lua
 -- 2010 August 27
@@ -542,4 +542,151 @@ test:do_catchsql_test(
         1, "Type mismatch: can not convert varbinary to unsigned"
     })
 
+test:do_execsql_test(
+    "func-5-6.6.1", [[
+        SELECT length(NULL);
+    ]],{
+        ""
+    })
+
+test:do_catchsql_test(
+    "func-5-6.6.2", [[
+        SELECT length(123);
+    ]], {
+        1, "Type mismatch: can not convert 123 to string"
+    })
+
+test:do_catchsql_test(
+    "func-5-6.6.3", [[
+        SELECT length(-123);
+    ]], {
+        1, "Type mismatch: can not convert -123 to string"
+    })
+
+test:do_catchsql_test(
+    "func-5-6.6.4", [[
+        SELECT length(-5.5);
+    ]], {
+        1, "Type mismatch: can not convert -5.5 to string"
+    })
+
+test:do_execsql_test(
+    "func-5-6.6.5", [[
+        SELECT length('-123');
+    ]], {
+        4
+    })
+
+test:do_catchsql_test(
+    "func-5-6.6.6", [[
+        SELECT length(false);
+    ]], {
+        1, "Type mismatch: can not convert FALSE to string"
+    })
+
+test:do_execsql_test(
+    "func-5-6.6.7", [[
+        SELECT length(X'3334');
+    ]], {
+        2
+    })
+
+test:do_execsql_test(
+    "func-5-6.7.1", [[
+        SELECT char_length(NULL);
+    ]],{
+        ""
+    })
+
+test:do_catchsql_test(
+    "func-5-6.7.2", [[
+        SELECT char_length(123);
+    ]], {
+        1, "Type mismatch: can not convert 123 to string"
+    })
+
+test:do_catchsql_test(
+    "func-5-6.7.3", [[
+        SELECT char_length(-123);
+    ]], {
+        1, "Type mismatch: can not convert -123 to string"
+    })
+
+test:do_catchsql_test(
+    "func-5-6.7.4", [[
+        SELECT char_length(-5.5);
+    ]], {
+        1, "Type mismatch: can not convert -5.5 to string"
+    })
+
+test:do_execsql_test(
+    "func-5-6.7.5", [[
+        SELECT char_length('-123');
+    ]], {
+        4
+    })
+
+test:do_catchsql_test(
+    "func-5-6.7.6", [[
+        SELECT char_length(false);
+    ]], {
+        1, "Type mismatch: can not convert FALSE to string"
+    })
+
+test:do_execsql_test(
+    "func-5-6.7.7", [[
+        SELECT char_length(X'3334');
+    ]], {
+        2
+    })
+
+test:do_execsql_test(
+    "func-5-6.8.1", [[
+        SELECT character_length(NULL);
+    ]],{
+        ""
+    })
+
+test:do_catchsql_test(
+    "func-5-6.8.2", [[
+        SELECT character_length(123);
+    ]], {
+        1, "Type mismatch: can not convert 123 to string"
+    })
+
+test:do_catchsql_test(
+    "func-5-6.8.3", [[
+        SELECT character_length(-123);
+    ]], {
+        1, "Type mismatch: can not convert -123 to string"
+    })
+
+test:do_catchsql_test(
+    "func-5-6.8.4", [[
+        SELECT character_length(-5.5);
+    ]], {
+        1, "Type mismatch: can not convert -5.5 to string"
+    })
+
+test:do_execsql_test(
+    "func-5-6.8.5", [[
+        SELECT character_length('-123');
+    ]], {
+        4
+    })
+
+test:do_catchsql_test(
+    "func-5-6.8.6", [[
+        SELECT character_length(false);
+    ]], {
+        1, "Type mismatch: can not convert FALSE to string"
+    })
+
+test:do_execsql_test(
+    "func-5-6.8.7", [[
+        SELECT character_length(X'3334');
+    ]], {
+        2
+    })
+
 test:finish_test()
diff --git a/test/sql-tap/orderby1.test.lua b/test/sql-tap/orderby1.test.lua
index 51e8d301f..95a8de487 100755
--- a/test/sql-tap/orderby1.test.lua
+++ b/test/sql-tap/orderby1.test.lua
@@ -735,7 +735,7 @@ test:do_execsql_test(
         SELECT (
           SELECT 'hardware' FROM ( 
             SELECT 'software' ORDER BY 'firmware' ASC, 'sportswear' DESC
-          ) GROUP BY 1 HAVING length(b) <> 0
+          ) GROUP BY 1 HAVING length(CAST(b AS STRING)) <> 0
         )
         FROM abc;
     ]], {
diff --git a/test/sql/boolean.result b/test/sql/boolean.result
index c470ebd40..39098b1f4 100644
--- a/test/sql/boolean.result
+++ b/test/sql/boolean.result
@@ -314,14 +314,8 @@ SELECT quote(a) FROM t0;
 -- gh-4462: LENGTH didn't take BOOLEAN arguments.
 SELECT length(a) FROM t0;
  | ---
- | - metadata:
- |   - name: length(a)
- |     type: integer
- |   rows:
- |   - [5]
- |   - [4]
- |   - [null]
- |   - [null]
+ | - null
+ | - 'Type mismatch: can not convert FALSE to string'
  | ...
 SELECT typeof(a) FROM t0;
  | ---
-- 
2.25.1

  parent reply	other threads:[~2020-07-16 14:45 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-16 14:45 [Tarantool-patches] [PATCH v6 00/22] sql: change implicit cast imeevma
2020-07-16 14:45 ` [Tarantool-patches] [PATCH v6 01/22] sql: change implicit cast for assignment imeevma
2020-07-16 14:45 ` [Tarantool-patches] [PATCH v6 02/22] sql: use ApplyType to check function arguments imeevma
2020-07-16 14:45 ` [Tarantool-patches] [PATCH v6 03/22] sql: check args of abs() imeevma
2020-07-16 16:12   ` Nikita Pettik
2020-07-16 14:45 ` [Tarantool-patches] [PATCH v6 04/22] sql: check args of avg(), sum() and total() imeevma
2020-07-16 16:21   ` Nikita Pettik
2020-07-16 14:45 ` [Tarantool-patches] [PATCH v6 05/22] sql: check args of char() imeevma
2020-07-16 16:27   ` Nikita Pettik
2020-07-16 14:45 ` imeevma [this message]
2020-07-16 16:31   ` [Tarantool-patches] [PATCH v6 06/22] sql: check args of length() Nikita Pettik
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 07/22] sql: check operands of LIKE imeevma
2020-07-16 17:03   ` Nikita Pettik
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 08/22] sql: check args of lower() and upper() imeevma
2020-07-16 17:09   ` Nikita Pettik
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 09/22] sql: check args of position() imeevma
2020-07-16 17:28   ` Nikita Pettik
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 10/22] sql: check args of randomblob() imeevma
2020-07-16 17:28   ` Nikita Pettik
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 11/22] sql: check args of replace() imeevma
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 12/22] sql: check args of round() imeevma
2020-07-16 14:46 ` [Tarantool-patches] [PATCH v6 13/22] sql: check args of soundex() imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 14/22] sql: check args of substr() imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 15/22] sql: check args of unicode() imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 16/22] sql: check args of zeroblob() imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 17/22] sql: remove unused DOUBLE to INTEGER conversion imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 18/22] sql: add implicit cast between numbers in OP_Seek* imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 19/22] sql: change comparison between numbers using index imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 20/22] sql: remove implicit cast from comparison opcodes imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 21/22] sql: fix implicit cast in opcode MustBeInt imeevma
2020-07-16 14:47 ` [Tarantool-patches] [PATCH v6 22/22] sql: remove implicit cast from MakeRecord opcode imeevma

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=e8f345be824a3b1f35ad862067b683e0fc695f9b.1594909974.git.imeevma@gmail.com \
    --to=imeevma@tarantool.org \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=tsafin@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v6 06/22] sql: check args of length()' \
    /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