<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hello! Consider some comments please.<div class="">Diff with previous version will be at the end.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Sep 11, 2018, at 15:03, Alex Khatskevich <<a href="mailto:avkhatskevich@tarantool.org" class="">avkhatskevich@tarantool.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">
<div text="#000000" bgcolor="#FFFFFF" class="">
<br class="">
<blockquote type="cite" cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org" class="">
<div class="">
<div class="">
<blockquote type="cite" class="">
<div class="">
<div text="#000000" bgcolor="#FFFFFF" class="">
<blockquote type="cite" cite="mid:E3BCC6A6-A137-4887-BD78-844A3F228441@tarantool.org" class="">
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<div class="">
<blockquote type="cite" class="">
<div class="">
<blockquote type="cite" style="font-family:
Helvetica; font-size: 12px; font-style:
normal; font-variant-caps: normal;
font-weight: normal; letter-spacing:
normal; orphans: auto; text-align: start;
text-indent: 0px; text-transform: none;
white-space: normal; widows: auto;
word-spacing: 0px;
-webkit-text-size-adjust: auto;
-webkit-text-stroke-width: 0px;
text-decoration: none;" class=""><br class="">
-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span> "ESCAPE
expression must be a single character",<br class="">
+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span> "ESCAPE
expression must be a"<br class="">
+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span> "
single character",<br class="">
</blockquote>
<span style="caret-color: rgb(0, 0, 0);
font-family: Helvetica; font-size: 12px;
font-style: normal; font-variant-caps:
normal; font-weight: normal;
letter-spacing: normal; text-align: start;
text-indent: 0px; text-transform: none;
white-space: normal; word-spacing: 0px;
-webkit-text-stroke-width: 0px;
text-decoration: none; float: none;
display: inline !important;" class="">Do
not split error messages at the middle of
a sentence. It makes errors ungreppable.</span><br style="caret-color: rgb(0, 0, 0);
font-family: Helvetica; font-size: 12px;
font-style: normal; font-variant-caps:
normal; font-weight: normal;
letter-spacing: normal; text-align: start;
text-indent: 0px; text-transform: none;
white-space: normal; word-spacing: 0px;
-webkit-text-stroke-width: 0px;
text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0);
font-family: Helvetica; font-size: 12px;
font-style: normal; font-variant-caps:
normal; font-weight: normal;
letter-spacing: normal; text-align: start;
text-indent: 0px; text-transform: none;
white-space: normal; word-spacing: 0px;
-webkit-text-stroke-width: 0px;
text-decoration: none; float: none;
display: inline !important;" class="">Make
it <80 somehow different.</span><br style="caret-color: rgb(0, 0, 0);
font-family: Helvetica; font-size: 12px;
font-style: normal; font-variant-caps:
normal; font-weight: normal;
letter-spacing: normal; text-align: start;
text-indent: 0px; text-transform: none;
white-space: normal; word-spacing: 0px;
-webkit-text-stroke-width: 0px;
text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0);
font-family: Helvetica; font-size: 12px;
font-style: normal; font-variant-caps:
normal; font-weight: normal;
letter-spacing: normal; text-align: start;
text-indent: 0px; text-transform: none;
white-space: normal; word-spacing: 0px;
-webkit-text-stroke-width: 0px;
text-decoration: none;" class="">
</div>
</blockquote>
<div class=""><br class="">
</div>
<div class="">Have already been discussed in
this thread.</div>
</div>
</div>
</div>
</blockquote>
I suppose that we concluded to try to fit into 80 and
split the string only<br class="">
in case it is impossible.<br class="">
</div>
</div>
</blockquote>
<div class=""><br class="">
</div>
<div class="">I don’t think so. Anyways, Alexander could you please
give your thoughts?</div>
</div>
</div>
</blockquote>
Discussed with Nikita, Alexander, Vladimir, Kirill... Conclusion:
use `const char temp variable` if possible.<br class="">
like this:<br class="">
```
<br class="">
const char *const err_msg =
<br class="">
"ESCAPE expression must be a single character";
<br class="">
if (sqlite3Utf8CharLen((char *)zEsc, -1) != 1) {
<br class="">
sqlite3_result_error(context,
<br class="">
err_msg,
<br class="">
-1);
<br class="">
return;
<br class="">
```
<br class="">
<br class="">
If it does not help (but it is) split the message.<br class=""></div></div></blockquote><div><br class=""></div><div>Splitted both error messages.</div><br class=""><blockquote type="cite" class=""><div class=""><div text="#000000" bgcolor="#FFFFFF" class="">
<blockquote type="cite" cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org" class="">
<div class="">
<div class="">
<blockquote type="cite" class="">
<div class="">
<div text="#000000" bgcolor="#FFFFFF" class="">
<blockquote type="cite" cite="mid:E3BCC6A6-A137-4887-BD78-844A3F228441@tarantool.org" class="">
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">diff --git
a/test/sql-tap/e_expr.test.lua
b/test/sql-tap/e_expr.test.lua</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">index
162026845..0d69e8535 100755</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">---
a/test/sql-tap/e_expr.test.lua</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">+++
b/test/sql-tap/e_expr.test.lua</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">@@ -1,6 +1,6 @@</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> #!/usr/bin/env
tarantool</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> test =
require("sqltester")</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">-test:plan(11521)</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">+test:plan(10647)</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> </div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> --!./tcltestrunner.lua</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> -- 2010 July 16</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">@@ -77,7 +77,7 @@
local operations = {</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"<>",
"ne1"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"!=",
"ne2"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"IS",
"is"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">- {"LIKE",
"like"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">+-- {"LIKE",
"like"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"AND",
"and"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"OR",
"or"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"MATCH",
"match"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">@@ -96,8 +96,9 @@
operations = {</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"<<",
">>", "&", "|"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> {"<",
"<=", ">", ">="},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class=""> -- Another NOTE:
MATCH & REGEXP aren't supported in
Tarantool &</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">--- <span class="Apple-tab-span" style="white-space:pre"> </span>
are waiting for their hour.</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">- {"=", "==",
"!=", "<>", "LIKE"}, --"MATCH",
"REGEXP"},</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">+--
are waiting for their hour, don't confuse them</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">+--
being commented with commenting of "LIKE".</div>
<div dir="auto" style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">+ {"=", "==",
"!=", "<>"}, --"LIKE"}, --"MATCH",
"REGEXP"},</div>
</div>
</div>
</div>
</blockquote>
Delete Like. No one returns here.<br class="">
</div>
</div>
</blockquote>
<div class=""><br class="">
</div>
<div class="">It’s a table of all of the operators thus I think it
still worth leaving it there.</div>
<div class="">Who knows, it may be that someone will revive tests for
LIKE.</div>
</div>
</div>
</blockquote>
Delete Like. No one returns here.<br class="">
We do not need a garbage. Like is not relevant anymore for this
test.<br class=""></div></div></blockquote><div><br class=""></div><div>Deleted.</div><br class=""><blockquote type="cite" class=""><div text="#000000" bgcolor="#FFFFFF" class="">
<blockquote type="cite" cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org" class="">
<div class="">
<div class=""><br class=""></div><div class="">
<div class=""> /*</div>
<div class="">- * Maximum length (in bytes) of the pattern in a LIKE or
GLOB</div>
<div class="">- * operator.</div>
<div class="">+ * Maximum length (in bytes) of the pattern in a LIKE
operator.</div>
<div class=""> */</div>
<div class=""> #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH</div>
<div class=""> #define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000</div>
<div class="">diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c</div>
<div class="">index 0c978142d..3f10f4d68 100644</div>
<div class="">--- a/src/box/sql/vdbe.c</div>
<div class="">+++ b/src/box/sql/vdbe.c</div>
<div class="">@@ -5521,7 +5521,7 @@ vdbe_return:</div>
<div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>testcase(
nVmStep>0);</div>
<div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>p->aCounter[SQLITE_STMTSTATUS_VM_STEP]
+= (int)nVmStep;</div>
<div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>assert(rc!=SQLITE_OK
|| nExtraDelete==0</div>
<div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>||
sqlite3_strlike("DELETE%",p->zSql,0)!=0</div>
<div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>||
sql_strlike_ci("DELETE%", p->zSql, 0) != 0</div>
<div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>);</div>
<div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return
rc;</div>
<div class=""> </div>
<div class="">diff --git a/src/box/sql/wherecode.c
b/src/box/sql/wherecode.c</div>
<div class="">index c35c25ac4..f864ea7fa 100644</div>
<div class="">--- a/src/box/sql/wherecode.c</div>
<div class="">+++ b/src/box/sql/wherecode.c</div>
<div class="">@@ -339,7 +339,7 @@ sqlite3WhereAddScanStatus(Vdbe * v,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Vdbe to add scanstatus entry to */</div>
<div class=""> * automatically disabled. In this way, terms get
disabled if derived</div>
<div class=""> * virtual terms are tested first. For example:</div>
<div class=""> *</div>
<div class="">- * x GLOB 'abc*' AND x>='abc' AND x<'acd'</div>
<div class="">+ * x LIKE 'abc%' AND x>='abc' AND x<'acd'</div>
<div class=""> * \___________/ \______/ \_____/</div>
<div class=""> * parent child1 child2</div>
<div class=""> *</div>
<div class="">diff --git a/src/box/sql/whereexpr.c
b/src/box/sql/whereexpr.c</div>
<div class="">index 612868695..2d9fb6453 100644</div>
<div class="">--- a/src/box/sql/whereexpr.c</div>
<div class="">+++ b/src/box/sql/whereexpr.c</div>
<div class="">@@ -218,38 +218,61 @@ operatorMask(int op)</div>
<div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return
c;</div>
<div class=""> }</div>
<div class=""> </div>
<div class="">+/**</div>
<div class="">+ * Wildcard characters.</div>
<div class="">+ */</div>
<div class="">+#define match_one '_'</div>
<div class="">+#define match_all '%'</div>
</div>
</div>
</blockquote>
If possible - move the define to a header which both (whereexpr and
func) file include.<br class="">
This also require to give more descriptive name, e.g.
LIKE_MATCH_ONE.<br class=""></div></blockquote><div><br class=""></div><div>Moved them to sqliteInt.h and renamed to:</div><div> 1) `MATCH_ALL_WILDCARD`.</div><div> 2) `MATCH_ONE_WILDCARD`.</div><div> </div><blockquote type="cite" class=""><div text="#000000" bgcolor="#FFFFFF" class=""><blockquote type="cite" cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org" class=""><div class=""><div class="">
<div class=""> for _, val in ipairs(test_cases12) do</div>
<div class="">@@ -1802,7 +1792,7 @@ test:do_execsql_test(</div>
<div class=""> })</div>
<div class=""> </div>
<div class=""> ---------------------------------------------------------------------------</div>
<div class="">--- Test the statements related to the LIKE and GLOB
operators.</div>
<div class="">+-- Test the statements related to the LIKE operator.</div>
<div class=""> --</div>
<div class=""> -- EVIDENCE-OF: R-16584-60189 The LIKE operator does a
pattern matching</div>
<div class=""> -- comparison.</div>
<div class="">@@ -2274,102 +2264,38 @@ test:do_execsql_test(</div>
<div class=""> -- </e_expr-16.1.7></div>
<div class=""> })</div>
<div class=""> </div>
<div class="">--- EVIDENCE-OF: R-52087-12043 The GLOB operator is
similar to LIKE but</div>
<div class="">--- uses the Unix file globbing syntax for its wildcards.</div>
<div class="">---</div>
<div class="">--- EVIDENCE-OF: R-09813-17279 Also, GLOB is case
sensitive, unlike LIKE.</div>
<div class="">+-- EVIDENCE-OF: R-39616-20555 LIKE may be preceded by
the</div>
<div class="">+-- NOT keyword to invert the sense of the test.</div>
<div class=""> --</div>
<div class=""> test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.1",</div>
<div class="">- [[</div>
<div class="">- SELECT 'abcxyz' GLOB 'abc%'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.1.1></div>
<div class="">- 0</div>
<div class="">- -- </e_expr-17.1.1></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.2",</div>
<div class="">- [[</div>
<div class="">- SELECT 'abcxyz' GLOB 'abc*'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.1.2></div>
<div class="">- 1</div>
<div class="">- -- </e_expr-17.1.2></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.3",</div>
<div class="">- [[</div>
<div class="">- SELECT 'abcxyz' GLOB 'abc___'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.1.3></div>
<div class="">- 0</div>
<div class="">- -- </e_expr-17.1.3></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.4",</div>
<div class="">- [[</div>
<div class="">- SELECT 'abcxyz' GLOB 'abc???'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.1.4></div>
<div class="">- 1</div>
<div class="">- -- </e_expr-17.1.4></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.5",</div>
<div class="">+ "e_expr-17.2.0",</div>
<div class=""> [[</div>
<div class="">- SELECT 'abcxyz' GLOB 'abc*'</div>
<div class="">+ PRAGMA case_sensitive_like = 1;</div>
<div class="">+ SELECT 'abcxyz' NOT LIKE 'ABC%';</div>
<div class=""> ]], {</div>
<div class="">- -- <e_expr-17.1.5></div>
<div class="">+ -- <e_expr-17.2.0></div>
<div class=""> 1</div>
<div class="">- -- </e_expr-17.1.5></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.6",</div>
<div class="">- [[</div>
<div class="">- SELECT 'ABCxyz' GLOB 'abc*'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.1.6></div>
<div class="">- 0</div>
<div class="">- -- </e_expr-17.1.6></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.1.7",</div>
<div class="">- [[</div>
<div class="">- SELECT 'abcxyz' GLOB 'ABC*'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.1.7></div>
<div class="">- 0</div>
<div class="">- -- </e_expr-17.1.7></div>
<div class="">+ -- </e_expr-17.2.0></div>
<div class=""> })</div>
<div class=""> </div>
<div class="">--- EVIDENCE-OF: R-39616-20555 Both GLOB and LIKE may be
preceded by the</div>
<div class="">--- NOT keyword to invert the sense of the test.</div>
<div class="">---</div>
<div class=""> test:do_execsql_test(</div>
<div class=""> "e_expr-17.2.1",</div>
<div class=""> [[</div>
<div class="">- SELECT 'abcxyz' NOT GLOB 'ABC*'</div>
<div class="">+ SELECT 'abcxyz' NOT LIKE 'abc%'</div>
<div class=""> ]], {</div>
<div class=""> -- <e_expr-17.2.1></div>
<div class="">- 1</div>
<div class="">+ 0</div>
<div class=""> -- </e_expr-17.2.1></div>
<div class=""> })</div>
<div class=""> </div>
<div class=""> test:do_execsql_test(</div>
<div class=""> "e_expr-17.2.2",</div>
<div class=""> [[</div>
<div class="">- SELECT 'abcxyz' NOT GLOB 'abc*'</div>
<div class="">+ PRAGMA case_sensitive_like = 0</div>
<div class=""> ]], {</div>
</div>
</div>
</blockquote>
delete 17.2.1 17.2.2 (it was creaget for glob, like tested below),
and move <br class="">
`PRAGMA case_sensitive_like = 0` out of the test (it is not a test)
(use just test:execsql or box.exequte)<br class=""></div></blockquote><div><br class=""></div><div>Done.</div><br class=""><blockquote type="cite" class=""><div class=""><div text="#000000" bgcolor="#FFFFFF" class="">
<blockquote type="cite" cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org" class="">
<div class="">
<div class="">
<div class=""> -- <e_expr-17.2.2></div>
<div class="">- 0</div>
<div class="">- -- </e_expr-17.2.2></div>
<div class="">+</div>
<div class="">+ -- <e_expr-17.2.2></div>
<div class=""> })</div>
<div class=""> </div>
<div class=""> test:do_execsql_test(</div>
<div class="">@@ -2448,62 +2374,6 @@ if 0>0 then</div>
<div class=""> db("nullvalue", "")</div>
<div class=""> end</div>
<div class=""> </div>
<div class="">--- EVIDENCE-OF: R-39414-35489 The infix GLOB operator is
implemented by</div>
<div class="">--- calling the function glob(Y,X) and can be modified by
overriding that</div>
<div class="">--- function.</div>
<div class="">-</div>
<div class="">-local globargs = {}</div>
<div class="">-local function globfunc(...)</div>
<div class="">- local args = {...}</div>
<div class="">- for i, v in ipairs(args) do</div>
<div class="">- table.insert(globargs, v)</div>
<div class="">- end</div>
<div class="">- return 1</div>
<div class="">-end</div>
<div class="">-box.internal.sql_create_function("GLOB", globfunc, 2)</div>
<div class="">---db("func", "glob", "-argcount", 2, "globfunc")</div>
</div>
</div>
</blockquote>
Do not delete this test. Rewrite it for like.<br class=""></div></div></blockquote><div><br class=""></div><div>There’re literally almost the same tests for like (15.1.x).</div><br class=""><blockquote type="cite" class=""><div class=""><div text="#000000" bgcolor="#FFFFFF" class="">
<blockquote type="cite" cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org" class="">
<div class="">
<div class="">
<div class="">-</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.3.1",</div>
<div class="">- [[</div>
<div class="">- SELECT 'abc' GLOB 'def'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.3.1></div>
<div class="">- 1</div>
<div class="">- -- </e_expr-17.3.1></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_test(</div>
<div class="">- "e_expr-17.3.2",</div>
<div class="">- function()</div>
<div class="">- return globargs</div>
<div class="">- end, {</div>
<div class="">- -- <e_expr-17.3.2></div>
<div class="">- "def", "abc"</div>
<div class="">- -- </e_expr-17.3.2></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-globargs = { }</div>
<div class="">-test:do_execsql_test(</div>
<div class="">- "e_expr-17.3.3",</div>
<div class="">- [[</div>
<div class="">- SELECT 'X' NOT GLOB 'Y'</div>
<div class="">- ]], {</div>
<div class="">- -- <e_expr-17.3.3></div>
<div class="">- 0</div>
<div class="">- -- </e_expr-17.3.3></div>
<div class="">- })</div>
<div class="">-</div>
<div class="">-test:do_test(</div>
<div class="">- "e_expr-17.3.4",</div>
<div class="">- function()</div>
<div class="">- return globargs</div>
<div class="">- end, {</div>
<div class="">- -- <e_expr-17.3.4></div>
<div class="">- "Y", "X"</div>
<div class="">- -- </e_expr-17.3.4></div>
<div class="">- })</div>
<div class="">-</div>
<div class=""> --sqlite3("db", "test.db")</div>
<div class=""> -- EVIDENCE-OF: R-41650-20872 No regexp() user function
is defined by</div>
<div class=""> -- default and so use of the REGEXP operator will
normally result in an</div>
<div class="">diff --git
a/test/sql-tap/gh-3251-string-pattern-comparison.test.lua
b/test/sql-tap/gh-3251-string-pattern-comparison.test.lua</div>
<div class="">index addf0e36d..a6d822ccd 100755</div>
</div>
</div>
</blockquote>
</div>
</div></blockquote></div><br class=""></div><div class="">diff:</div><div class=""><br class=""></div><div class=""><div class="">diff --git a/src/box/sql/func.c b/src/box/sql/func.c</div><div class="">index 28b435ae3..f57967bd8 100644</div><div class="">--- a/src/box/sql/func.c</div><div class="">+++ b/src/box/sql/func.c</div><div class="">@@ -631,12 +631,6 @@ static const int case_insensitive_like = 1;</div><div class=""> */</div><div class=""> static const int case_sensitive_like = 0;</div><div class=""> </div><div class="">-/**</div><div class="">- * Wildcards.</div><div class="">- */</div><div class="">-#define match_one '_'</div><div class="">-#define match_all '%'</div><div class="">-</div><div class=""> /**</div><div class=""> * Possible error returns from sql_utf8_pattern_compare().</div><div class=""> */</div><div class="">@@ -693,7 +687,7 @@ sql_utf8_pattern_compare(const char *pattern,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>c = Utf8Read(pattern, pattern_end);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (c == SQL_INVALID_UTF8_SYMBOL)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return SQL_INVALID_PATTERN;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>if (c == match_all) {</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (c == MATCH_ALL_WILDCARD) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>/**</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> * Skip over multiple "%" characters in</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> * the pattern. If there are also "_"</div><div class="">@@ -705,9 +699,10 @@ sql_utf8_pattern_compare(const char *pattern,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> SQL_END_OF_STRING) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (c == SQL_INVALID_UTF8_SYMBOL)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return SQL_INVALID_PATTERN;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>if (c != match_all && c != match_one)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (c != MATCH_ALL_WILDCARD &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span> c != MATCH_ONE_WILDCARD)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>break;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>if (c == match_one &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (c == MATCH_ONE_WILDCARD &&</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> (c2 = Utf8Read(string, string_end)) ==</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> SQL_END_OF_STRING)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return SQL_NOWILDCARDMATCH;</div><div class="">@@ -801,7 +796,7 @@ sql_utf8_pattern_compare(const char *pattern,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> c == u_tolower(c2))</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>if (c == match_one && pattern != zEscaped &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (c == MATCH_ONE_WILDCARD && pattern != zEscaped &&</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span> c2 != SQL_END_OF_STRING)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return SQL_NOMATCH;</div><div class="">@@ -894,11 +889,10 @@ likeFunc(sqlite3_context *context, int argc, sqlite3_value **argv)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>const unsigned char *zEsc = sqlite3_value_text(argv[2]);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (zEsc == 0)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>const char *const err_msg =</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>"ESCAPE expression must be a single character";</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (sqlite3Utf8CharLen((char *)zEsc, -1) != 1) {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context,</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span> "ESCAPE expression must be a"</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span> " single character",</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span> -1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context, err_msg, -1);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>escape = sqlite3Utf8Read(&zEsc);</div><div class="">@@ -911,8 +905,9 @@ likeFunc(sqlite3_context *context, int argc, sqlite3_value **argv)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>int res;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>res = sql_utf8_pattern_compare(zB, zA, *is_like_ci, escape);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (res == SQL_INVALID_PATTERN) {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context, "LIKE pattern can only contain"</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span> " UTF-8 characters", -1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>const char *const err_msg =</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>"LIKE pattern can only contain UTF-8 characters";</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context, err_msg, -1);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_int(context, res == SQL_MATCH);</div><div class="">diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h</div><div class="">index a805adf22..420c76bfe 100644</div><div class="">--- a/src/box/sql/sqliteInt.h</div><div class="">+++ b/src/box/sql/sqliteInt.h</div><div class="">@@ -564,6 +564,12 @@ sqlite3_snprintf(int, char *, const char *, ...);</div><div class=""> char *</div><div class=""> sqlite3_vsnprintf(int, char *, const char *, va_list);</div><div class=""> </div><div class="">+/**</div><div class="">+ * Wildcard characters used in REGEXP-like operators.</div><div class="">+ */</div><div class="">+#define MATCH_ONE_WILDCARD '_'</div><div class="">+#define MATCH_ALL_WILDCARD '%'</div><div class="">+</div><div class=""> int</div><div class=""> sql_strlike_cs(const char *zLike, const char *zStr, unsigned int cEsc);</div><div class=""> </div><div class="">diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c</div><div class="">index 2d9fb6453..616acc640 100644</div><div class="">--- a/src/box/sql/whereexpr.c</div><div class="">+++ b/src/box/sql/whereexpr.c</div><div class="">@@ -218,12 +218,6 @@ operatorMask(int op)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>return c;</div><div class=""> }</div><div class=""> </div><div class="">-/**</div><div class="">- * Wildcard characters.</div><div class="">- */</div><div class="">-#define match_one '_'</div><div class="">-#define match_all '%'</div><div class="">-</div><div class=""> #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION</div><div class=""> /**</div><div class=""> * Check to see if the given expression is a LIKE operator that</div><div class="">@@ -305,11 +299,13 @@ is_like(Parse *pParse,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (z) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>cnt = 0;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>while ((c = z[cnt]) != 0 && c != match_one && c != match_all)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>while ((c = z[cnt]) != 0 && c != MATCH_ONE_WILDCARD &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span> c != MATCH_ALL_WILDCARD)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>cnt++;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (cnt != 0 && 255 != (u8) z[cnt - 1]) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>Expr *pPrefix;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre"> </span>*pisComplete = c == match_all && z[cnt + 1] == 0;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span>*pisComplete = c == MATCH_ALL_WILDCARD &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre"> </span> z[cnt + 1] == 0;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>pPrefix = sqlite3Expr(db, TK_STRING, z);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>if (pPrefix)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre"> </span>pPrefix->u.zToken[cnt] = 0;</div><div class="">diff --git a/test/sql-tap/e_expr.test.lua b/test/sql-tap/e_expr.test.lua</div><div class="">index 0d69e8535..6d1edcfd0 100755</div><div class="">--- a/test/sql-tap/e_expr.test.lua</div><div class="">+++ b/test/sql-tap/e_expr.test.lua</div><div class="">@@ -77,7 +77,6 @@ local operations = {</div><div class=""> {"<>", "ne1"},</div><div class=""> {"!=", "ne2"},</div><div class=""> {"IS", "is"},</div><div class="">--- {"LIKE", "like"},</div><div class=""> {"AND", "and"},</div><div class=""> {"OR", "or"},</div><div class=""> {"MATCH", "match"},</div><div class="">@@ -98,7 +97,7 @@ operations = {</div><div class=""> -- Another NOTE: MATCH & REGEXP aren't supported in Tarantool &</div><div class=""> -- are waiting for their hour, don't confuse them</div><div class=""> -- being commented with commenting of "LIKE".</div><div class="">- {"=", "==", "!=", "<>"}, --"LIKE"}, --"MATCH", "REGEXP"},</div><div class="">+ {"=", "==", "!=", "<>"}, --"MATCH", "REGEXP"},</div><div class=""> {"AND"},</div><div class=""> {"OR"},</div><div class=""> }</div><div class="">@@ -2278,10 +2277,12 @@ test:do_execsql_test(</div><div class=""> -- </e_expr-17.2.0></div><div class=""> })</div><div class=""> </div><div class="">+test:execsql("PRAGMA case_sensitive_like = 0;")</div><div class="">+</div><div class=""> test:do_execsql_test(</div><div class=""> "e_expr-17.2.1",</div><div class=""> [[</div><div class="">- SELECT 'abcxyz' NOT LIKE 'abc%'</div><div class="">+ SELECT 'abcxyz' NOT LIKE 'ABC%'</div><div class=""> ]], {</div><div class=""> -- <e_expr-17.2.1></div><div class=""> 0</div><div class="">@@ -2290,85 +2291,65 @@ test:do_execsql_test(</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class=""> "e_expr-17.2.2",</div><div class="">- [[</div><div class="">- PRAGMA case_sensitive_like = 0</div><div class="">- ]], {</div><div class="">- -- <e_expr-17.2.2></div><div class="">-</div><div class="">- -- <e_expr-17.2.2></div><div class="">- })</div><div class="">-</div><div class="">-test:do_execsql_test(</div><div class="">- "e_expr-17.2.3",</div><div class="">- [[</div><div class="">- SELECT 'abcxyz' NOT LIKE 'ABC%'</div><div class="">- ]], {</div><div class="">- -- <e_expr-17.2.3></div><div class="">- 0</div><div class="">- -- </e_expr-17.2.3></div><div class="">- })</div><div class="">-</div><div class="">-test:do_execsql_test(</div><div class="">- "e_expr-17.2.4",</div><div class=""> [[</div><div class=""> SELECT 'abcxyz' NOT LIKE 'abc%'</div><div class=""> ]], {</div><div class="">- -- <e_expr-17.2.4></div><div class="">+ -- <e_expr-17.2.2></div><div class=""> 0</div><div class="">- -- </e_expr-17.2.4></div><div class="">+ -- </e_expr-17.2.2></div><div class=""> })</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class="">- "e_expr-17.2.5",</div><div class="">+ "e_expr-17.2.3",</div><div class=""> [[</div><div class=""> SELECT 'abdxyz' NOT LIKE 'abc%'</div><div class=""> ]], {</div><div class="">- -- <e_expr-17.2.5></div><div class="">+ -- <e_expr-17.2.3></div><div class=""> 1</div><div class="">- -- </e_expr-17.2.5></div><div class="">+ -- </e_expr-17.2.3></div><div class=""> })</div><div class=""> </div><div class=""> -- MUST_WORK_TEST uses access to nullvalue... (sql parameters) and built in functions</div><div class=""> if 0>0 then</div><div class=""> db("nullvalue", "null")</div><div class=""> test:do_execsql_test(</div><div class="">- "e_expr-17.2.6",</div><div class="">+ "e_expr-17.2.4",</div><div class=""> [[</div><div class=""> SELECT 'abcxyz' NOT GLOB NULL</div><div class=""> ]], {</div><div class="">- -- <e_expr-17.2.6></div><div class="">+ -- <e_expr-17.2.4></div><div class=""> "null"</div><div class="">- -- </e_expr-17.2.6></div><div class="">+ -- </e_expr-17.2.4></div><div class=""> })</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class="">- "e_expr-17.2.7",</div><div class="">+ "e_expr-17.2.5",</div><div class=""> [[</div><div class=""> SELECT 'abcxyz' NOT LIKE NULL</div><div class=""> ]], {</div><div class="">- -- <e_expr-17.2.7></div><div class="">+ -- <e_expr-17.2.5></div><div class=""> "null"</div><div class="">- -- </e_expr-17.2.7></div><div class="">+ -- </e_expr-17.2.5></div><div class=""> })</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class="">- "e_expr-17.2.8",</div><div class="">+ "e_expr-17.2.6",</div><div class=""> [[</div><div class=""> SELECT NULL NOT GLOB 'abc*'</div><div class=""> ]], {</div><div class="">- -- <e_expr-17.2.8></div><div class="">+ -- <e_expr-17.2.6></div><div class=""> "null"</div><div class="">- -- </e_expr-17.2.8></div><div class="">+ -- </e_expr-17.2.6></div><div class=""> })</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class="">- "e_expr-17.2.9",</div><div class="">+ "e_expr-17.2.7",</div><div class=""> [[</div><div class=""> SELECT NULL NOT LIKE 'ABC%'</div><div class=""> ]], {</div><div class="">- -- <e_expr-17.2.9></div><div class="">+ -- <e_expr-17.2.7></div><div class=""> "null"</div><div class="">- -- </e_expr-17.2.9></div><div class="">+ -- </e_expr-17.2.7></div><div class=""> })</div><div class=""> </div><div class=""> db("nullvalue", "")</div></div><div class=""><br class=""></div></body></html>