[tarantool-patches] [PATCH v1 1/1] sql: create CHAR_LENGTH() and CHARACTER_LENGTH()

imeevma at tarantool.org imeevma at tarantool.org
Wed May 8 16:15:25 MSK 2019


This patch creates SQL functions CHARACTER_LENGTH() and
CHAR_LENGTH(). These functions work the same way. Each of them
takes only one argument of type TEXT and returns its length.

Closes #3929

@TarantoolBot document
Title: SQL functions CHAR_LENGTH() and CHARACTER_LENGTH()

The SQL functions CHAR_LENGTH() and CHARACTER_LENGTH() take
exactly one argument of type TEXT and return its length. They
throw an error if the argument is of a different type or if more
than one argument is given.
---
https://github.com/tarantool/tarantool/issues/3929
https://github.com/tarantool/tarantool/tree/imeevma/gh-3929-character-length-functions

 src/box/sql/func.c          |  27 +++++++++
 test/sql-tap/func3.test.lua | 130 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 156 insertions(+), 1 deletion(-)

diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index bb7405e..01c271c 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -133,6 +133,29 @@ typeofFunc(sql_context * context, int NotUsed, sql_value ** argv)
 }
 
 /*
+ * Implementation of the char_length() and character_length()
+ * functions.
+ */
+static void
+char_length_func(sql_context *context, int argc, sql_value **argv)
+{
+	assert(argc == 1);
+	UNUSED_PARAMETER(argc);
+	if (sql_value_type(argv[0]) != MP_STR) {
+		diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT",
+			 mem_type_to_str(argv[0]));
+		context->isError = SQL_TARANTOOL_ERROR;
+		context->fErrorOrAux = 1;
+		return;
+	}
+	const unsigned char *z = sql_value_text(argv[0]);
+	if (z == NULL)
+		return;
+	int len = sql_utf8_char_count(z, sql_value_bytes(argv[0]));
+	sql_result_int(context, len);
+}
+
+/*
  * Implementation of the length() function
  */
 static void
@@ -1936,6 +1959,10 @@ sqlRegisterBuiltinFunctions(void)
 			  FIELD_TYPE_STRING),
 		FUNCTION2(length, 1, 0, 0, lengthFunc, SQL_FUNC_LENGTH,
 			  FIELD_TYPE_INTEGER),
+		FUNCTION(char_length, 1, 0, 0, char_length_func,
+			 FIELD_TYPE_INTEGER),
+		FUNCTION(character_length, 1, 0, 0, char_length_func,
+			 FIELD_TYPE_INTEGER),
 		FUNCTION(position, 2, 0, 1, position_func, FIELD_TYPE_INTEGER),
 		FUNCTION(printf, -1, 0, 0, printfFunc, FIELD_TYPE_STRING),
 		FUNCTION(unicode, 1, 0, 0, unicodeFunc, FIELD_TYPE_STRING),
diff --git a/test/sql-tap/func3.test.lua b/test/sql-tap/func3.test.lua
index 6d6411c..a3a548b 100755
--- a/test/sql-tap/func3.test.lua
+++ b/test/sql-tap/func3.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(25)
+test:plan(37)
 
 --!./tcltestrunner.lua
 -- 2010 August 27
@@ -284,6 +284,134 @@ test:do_test(
         return test:execsql "EXPLAIN SELECT likely(min(1.0+'2.0',4*11))"
     end, test:execsql "EXPLAIN SELECT min(1.0+'2.0',4*11)")
 
+--
+-- gh-3929: create SQL functions CHARACTER_LENGTH() and
+-- CHAR_LENGTH().
+--
+test:do_test(
+	"func3-6.1",
+	function()
+		local some_text = 'some text'
+		return test:execsql(string.format([[
+			SELECT LENGTH('%s'), CHAR_LENGTH('%s'), CHARACTER_LENGTH('%s');
+		]], some_text, some_text, some_text))
+	end, {
+		-- <func3-6.1>
+		9, 9, 9
+		-- </func3-6.1>
+	})
+
+test:do_test(
+	"func3-6.2",
+	function()
+		local some_text = 'какой-то текст'
+		return test:execsql(string.format([[
+			SELECT LENGTH('%s'), CHAR_LENGTH('%s'), CHARACTER_LENGTH('%s');
+		]], some_text, some_text, some_text))
+	end, {
+		-- <func3-6.2>
+		14, 14, 14
+		-- </func3-6.2>
+	})
+
+test:do_catchsql_test(
+	"func3-6.3",
+	[[
+		SELECT CHAR_LENGTH(12);
+	]], {
+		-- <func3-6.3>
+		1,"Inconsistent types: expected TEXT got INTEGER"
+		-- </func3-6.3>
+	})
+
+test:do_catchsql_test(
+	"func3-6.4",
+	[[
+		SELECT CHAR_LENGTH(12.34);
+	]], {
+		-- <func3-6.4>
+		1,"Inconsistent types: expected TEXT got REAL"
+		-- </func3-6.4>
+	})
+
+test:do_catchsql_test(
+	"func3-6.5",
+	[[
+		SELECT CHAR_LENGTH(x'12');
+	]], {
+		-- <func3-6.5>
+		1,"Inconsistent types: expected TEXT got BLOB"
+		-- </func3-6.5>
+	})
+
+test:do_catchsql_test(
+	"func3-6.6",
+	[[
+		SELECT CHAR_LENGTH(true);
+	]], {
+		-- <func3-6.6>
+		1,"Inconsistent types: expected TEXT got BOOLEAN"
+		-- </func3-6.6>
+	})
+
+test:do_catchsql_test(
+	"func3-6.7",
+	[[
+		SELECT CHARACTER_LENGTH(12);
+	]], {
+		-- <func3-6.7>
+		1,"Inconsistent types: expected TEXT got INTEGER"
+		-- </func3-6.7>
+	})
+
+test:do_catchsql_test(
+	"func3-6.8",
+	[[
+		SELECT CHARACTER_LENGTH(12.34);
+	]], {
+		-- <func3-6.8>
+		1,"Inconsistent types: expected TEXT got REAL"
+		-- </func3-6.8>
+	})
+
+test:do_catchsql_test(
+	"func3-6.9",
+	[[
+		SELECT CHARACTER_LENGTH(x'12');
+	]], {
+		-- <func3-6.9>
+		1,"Inconsistent types: expected TEXT got BLOB"
+		-- </func3-6.9>
+	})
+
+test:do_catchsql_test(
+	"func3-6.10",
+	[[
+		SELECT CHARACTER_LENGTH(true);
+	]], {
+		-- <func3-6.10>
+		1,"Inconsistent types: expected TEXT got BOOLEAN"
+		-- </func3-6.10>
+	})
 
+test:do_catchsql_test(
+	"func3-6.11",
+	[[
+		SELECT CHAR_LENGTH('abc', 'efg');
+	]], {
+		-- <func3-6.6>
+		1,"wrong number of arguments to function CHAR_LENGTH()"
+		-- </func3-6.6>
+	})
+
+test:do_catchsql_test(
+	"func3-6.12",
+	[[
+		SELECT CHARACTER_LENGTH('abc', 'efg');
+	]], {
+		-- <func3-6.7>
+		1,"wrong number of arguments to function CHARACTER_LENGTH()"
+		-- </func3-6.7>
+	})
 
 test:finish_test()
-- 
2.7.4





More information about the Tarantool-patches mailing list