From: Nikita Tatunov <hollow653@gmail.com> To: avkhatskevich@tarantool.org Cc: alexander.turenko@tarantool.org, tarantool-patches@freelists.org Subject: [tarantool-patches] Re: [PATCH] sql: LIKE & GLOB pattern comparison issue Date: Wed, 18 Jul 2018 18:57:39 +0300 [thread overview] Message-ID: <CAEi+_aq3ibC1=3sN4On=P9rHOEB=mZexKEMo5rf1t=3aa6MBTg@mail.gmail.com> (raw) In-Reply-To: <dcf5206b-892e-2def-a88a-8c8d6507dc57@tarantool.org> [-- Attachment #1: Type: text/plain, Size: 7712 bytes --] ср, 18 июл. 2018 г. в 18:53, Alex Khatskevich <avkhatskevich@tarantool.org>: > Once you have fixed comments, please apply a new full diff at the end of > email, to > continue review process. > Answer with a full diff to this email please (just paste as a plain text > output of `git diff` command) > > On 18.07.2018 18:24, Nikita Tatunov wrote: > > > Fixed it. > > Yeah, you're right. Fixed it. > > Isn't actual with the fix. > > Yeah, sure. > > > Sorry. Here it is: diff --git a/src/box/sql/func.c b/src/box/sql/func.c index c06e3bd..a7f7c17 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -617,13 +617,15 @@ struct compareInfo { u8 noCase; /* true to ignore case differences */ }; -/* - * For LIKE and GLOB matching on EBCDIC machines, assume that every - * character is exactly one byte in size. Also, provde the Utf8Read() - * macro for fast reading of the next character in the common case where - * the next character is ASCII. +/** + * Providing there are symbols in string s this macro returns + * UTF-8 code of character and pushes pointer to the next symbol + * in the string. Otherwise return code is SQL_END_OF_STRING. */ -#define Utf8Read(s, e) ucnv_getNextUChar(pUtf8conv, &s, e, &status) +#define Utf8Read(s, e) (s < e ?\ + ucnv_getNextUChar(pUtf8conv, &s, e, &status) : 0) + +#define SQL_END_OF_STRING 0 static const struct compareInfo globInfo = { '*', '?', '[', 0 }; @@ -698,29 +700,27 @@ patternCompare(const char * pattern, /* The glob pattern */ const char * string_end = string + strlen(string); UErrorCode status = U_ZERO_ERROR; - while (pattern < pattern_end){ - c = Utf8Read(pattern, pattern_end); + while ((c = Utf8Read(pattern, pattern_end))) { if (c == matchAll) { /* Match "*" */ /* Skip over multiple "*" characters in the pattern. If there * are also "?" characters, skip those as well, but consume a * single character of the input string for each "?" skipped */ - while (pattern < pattern_end){ - c = Utf8Read(pattern, pattern_end); + while ((c = Utf8Read(pattern, pattern_end))) { if (c != matchAll && c != matchOne) break; - if (c == matchOne - && Utf8Read(string, string_end) == 0) { + if (c == matchOne && + Utf8Read(string, string_end) == + SQL_END_OF_STRING) return SQLITE_NOWILDCARDMATCH; - } } /* "*" at the end of the pattern matches */ - if (pattern == pattern_end) + if (c == SQL_END_OF_STRING) return SQLITE_MATCH; if (c == matchOther) { if (pInfo->matchSet == 0) { c = Utf8Read(pattern, pattern_end); - if (c == 0) + if (c == SQL_END_OF_STRING) return SQLITE_NOWILDCARDMATCH; } else { /* "[...]" immediately follows the "*". We have to do a slow @@ -782,7 +782,7 @@ patternCompare(const char * pattern, /* The glob pattern */ if (c == matchOther) { if (pInfo->matchSet == 0) { c = Utf8Read(pattern, pattern_end); - if (c == 0) + if (c == SQL_END_OF_STRING) return SQLITE_NOMATCH; zEscaped = pattern; } else { @@ -802,7 +802,7 @@ patternCompare(const char * pattern, /* The glob pattern */ seen = 1; c2 = Utf8Read(pattern, pattern_end); } - while (c2 && c2 != ']') { + while (c2 != SQL_END_OF_STRING && c2 != ']') { if (c2 == '-' && pattern[0] != ']' && pattern < pattern_end && prior_c > 0) { @@ -839,7 +839,8 @@ patternCompare(const char * pattern, /* The glob pattern */ c == u_tolower(c2)) continue; } - if (c == matchOne && pattern != zEscaped && c2 != 0) + if (c == matchOne && pattern != zEscaped && + c2 != SQL_END_OF_STRING) continue; return SQLITE_NOMATCH; } diff --git a/test/sql-tap/like1.test.lua b/test/sql-tap/like1.test.lua new file mode 100755 index 0000000..807ee65 --- /dev/null +++ b/test/sql-tap/like1.test.lua @@ -0,0 +1,181 @@ +#!/usr/bin/env tarantool +test = require("sqltester") +test:plan(16) + +test:do_catchsql_test( + "like-test-1.1", + [[ + CREATE TABLE t2 (column1 INTEGER, + column2 VARCHAR(100), + column3 BLOB, + column4 FLOAT, + PRIMARY KEY (column1, column2)); + INSERT INTO t2 VALUES (1, 'AB', X'4142', 5.5); + INSERT INTO t2 VALUES (1, 'CD', X'2020', 1E4); + INSERT INTO t2 VALUES (2, 'AB', X'2020', 12.34567); + INSERT INTO t2 VALUES (-1000, '', X'', 0.0); + CREATE TABLE t1 (a INT PRIMARY KEY, str VARCHAR(100)); + INSERT INTO t1 VALUES (1, 'ab'); + INSERT INTO t1 VALUES (2, 'abCDF'); + INSERT INTO t1 VALUES (3, 'CDF'); + CREATE TABLE t (s1 char(2) primary key, s2 char(2)); + INSERT INTO t VALUES ('AB', 'AB'); + ]], { + -- <like-test-1.1> + 0 + -- <like-test-1.1> + }) + +test:do_execsql_test( + "like-test-1.2", + [[ + SELECT column1, column2, column1 * column4 FROM t2 WHERE column2 LIKE '_B'; + ]], { + -- <like-test-1.2> + 1, 'AB', 5.5, 2, 'AB', 24.69134 + -- <like-test-1.2> + }) + +test:do_execsql_test( + "like-test-1.3", + [[ + SELECT column1, column2 FROM t2 WHERE column2 LIKE '%B'; + ]], { + -- <like-test-1.3> + 1, 'AB', 2, 'AB' + -- <like-test-1.3> + }) + +test:do_execsql_test( + "like-test-1.4", + [[ + SELECT column1, column2 FROM t2 WHERE column2 LIKE 'A__'; + ]], { + -- <like-test-1.4> + + -- <like-test-1.4> + }) + +test:do_execsql_test( + "like-test-1.5", + [[ + SELECT column1, column2 FROM t2 WHERE column2 LIKE 'A_'; + ]], { + -- <like-test-1.5> + 1, 'AB', 2, 'AB' + -- <like-test-1.5> + }) + +test:do_execsql_test( + "like-test-1.6", + [[ + SELECT column1, column2 FROM t2 WHERE column2 LIKE 'A'; + ]], { + -- <like-test-1.6> + + -- <like-test-1.6> + }) + +test:do_execsql_test( + "like-test-1.7", + [[ + SELECT column1, column2 FROM t2 WHERE column2 LIKE '_'; + ]], { + -- <like-test-1.7> + + -- <like-test-1.7> + }) + +test:do_execsql_test( + "like-test-1.8", + [[ + SELECT * FROM t WHERE s1 LIKE '%A'; + ]], { + -- <like-test-1.8> + + -- <like-test-1.8> + }) + +test:do_execsql_test( + "like-test-1.9", + [[ + SELECT * FROM t WHERE s1 LIKE '%C'; + ]], { + -- <like-test-1.9> + + -- <like-test-1.9> + }) + +test:do_execsql_test( + "like-test-1.10", + [[ + SELECT * FROM t1 WHERE str LIKE '%df'; + ]], { + -- <like-test-1.10> + 2, 'abCDF', 3, 'CDF' + -- <like-test-1.10> + }) + +test:do_execsql_test( + "like-test-1.11", + [[ + SELECT * FROM t1 WHERE str LIKE 'a_'; + ]], { + -- <like-test-1.11> + 1, 'ab' + -- <like-test-1.11> + }) + +test:do_execsql_test( + "like-test-1.12", + [[ + SELECT column1, column2 FROM t2 WHERE column2 LIKE '__'; + ]], { + -- <like-test-1.12> + 1, 'AB', 1, 'CD', 2, 'AB' + -- <like-test-1.12> + }) + +test:do_execsql_test( + "like-test-1.13", + [[ + SELECT str FROM t1 WHERE str LIKE 'ab%'; + ]], { + -- <like-test-1.13> + 'ab', 'abCDF' + -- <like-test-1.13> + }) + +test:do_execsql_test( + "like-test-1.14", + [[ + SELECT str FROM t1 WHERE str LIKE 'abC%'; + ]], { + -- <like-test-1.14> + 'abCDF' + -- <like-test-1.14> + }) + +test:do_execsql_test( + "like-test-1.15", + [[ + SELECT str FROM t1 WHERE str LIKE 'a_%'; + ]], { + -- <like-test-1.15> + 'ab', 'abCDF' + -- <like-test-1.15> + }) + +test:do_execsql_test( + "like-test-1.16", + [[ + DROP TABLE t1; + DROP TABLE t2; + DROP TABLE t; + ]], { + -- <like-test-1.16> + + -- <like-test-1.16> + }) + +test:finish_test() [-- Attachment #2: Type: text/html, Size: 19060 bytes --]
next prev parent reply other threads:[~2018-07-18 15:57 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-28 12:47 [tarantool-patches] " N.Tatunov 2018-06-28 12:54 ` [tarantool-patches] " Hollow111 2018-07-18 2:43 ` Alexander Turenko 2018-07-18 5:51 ` Alex Khatskevich 2018-07-18 15:24 ` Nikita Tatunov 2018-07-18 15:53 ` Alex Khatskevich 2018-07-18 15:57 ` Nikita Tatunov [this message] 2018-07-18 17:10 ` Alexander Turenko 2018-07-19 11:14 ` Nikita Tatunov 2018-07-19 11:56 ` Alex Khatskevich 2018-07-27 11:28 ` Nikita Tatunov 2018-07-27 13:06 ` Alexander Turenko 2018-07-27 19:11 ` Nikita Tatunov 2018-07-27 20:22 ` Alexander Turenko 2018-07-31 13:27 ` Nikita Tatunov 2018-07-31 13:47 ` Alexander Turenko 2018-08-01 10:35 ` Nikita Tatunov 2018-08-01 10:51 ` Nikita Tatunov 2018-08-01 13:56 ` Alex Khatskevich 2018-08-01 18:10 ` Nikita Tatunov 2018-08-01 18:14 ` Nikita Tatunov 2018-08-08 12:38 ` Alex Khatskevich
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='CAEi+_aq3ibC1=3sN4On=P9rHOEB=mZexKEMo5rf1t=3aa6MBTg@mail.gmail.com' \ --to=hollow653@gmail.com \ --cc=alexander.turenko@tarantool.org \ --cc=avkhatskevich@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH] sql: LIKE & GLOB pattern comparison issue' \ /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