<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<br>
<blockquote type="cite"
cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org">
<div class="">
<div>
<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><br class="">
</div>
<div>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>
like this:<br>
```
<br>
const char *const err_msg =
<br>
"ESCAPE expression must be a single character";
<br>
if (sqlite3Utf8CharLen((char *)zEsc, -1) != 1) {
<br>
sqlite3_result_error(context,
<br>
err_msg,
<br>
-1);
<br>
return;
<br>
```
<br>
<br>
If it does not help (but it is) split the message.<br>
<blockquote type="cite"
cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org">
<div class="">
<div>
<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><br class="">
</div>
<div>It’s a table of all of the operators thus I think it
still worth leaving it there.</div>
<div>Who knows, it may be that someone will revive tests for
LIKE.</div>
</div>
</div>
</blockquote>
Delete Like. No one returns here.<br>
We do not need a garbage. Like is not relevant anymore for this
test.<br class="">
<blockquote type="cite"
cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org">
<div class="">
<div><br class="">
</div>
<div>
<div>diff --git a/extra/mkkeywordhash.c
b/extra/mkkeywordhash.c</div>
<div>index 990c4199f..1fee3a7f2 100644</div>
<div>--- a/extra/mkkeywordhash.c</div>
<div>+++ b/extra/mkkeywordhash.c</div>
<div>@@ -159,7 +159,6 @@ static Keyword aKeywordTable[] = {</div>
<div> { "FOR", "TK_FOR", TRIGGER,
true },</div>
<div> { "FOREIGN", "TK_FOREIGN", FKEY,
true },</div>
<div> { "FROM", "TK_FROM", ALWAYS,
true },</div>
<div>- { "GLOB", "TK_LIKE_KW", ALWAYS,
false },</div>
<div> { "GROUP", "TK_GROUP", ALWAYS,
true },</div>
<div> { "HAVING", "TK_HAVING", ALWAYS,
true },</div>
<div> { "IF", "TK_IF", ALWAYS,
true },</div>
<div>diff --git a/src/box/sql/analyze.c
b/src/box/sql/analyze.c</div>
<div>index 5f73f026e..fc7588c3f 100644</div>
<div>--- a/src/box/sql/analyze.c</div>
<div>+++ b/src/box/sql/analyze.c</div>
<div>@@ -829,7 +829,7 @@ analyzeOneTable(Parse * pParse,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Parser context */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>assert(pTab->tnum
!= 0);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(sqlite3_strlike("\\_%", pTab->def->name, '\\') == 0)
{</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(sql_strlike_ci("\\_%", pTab->def->name, '\\') == 0) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/*
Do not gather statistics on system tables */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>@@ -1333,11 +1333,10 @@ analysis_loader(void *data, int
argc, char **argv, char **unused)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/*
Position ptr at the end of stat string. */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>for
(; *z == ' ' || (*z >= '0' && *z <= '9');
++z);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>while
(z[0]) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(sqlite3_strglob("unordered*", z) == 0) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(sql_strlike_cs("unordered%", z, '[') == 0)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>index->def->opts.stat->is_unordered
= true;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}
else if (sqlite3_strglob("noskipscan*", z) == 0) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>else
if (sql_strlike_cs("noskipscan%", z, '[') == 0)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>index->def->opts.stat->skip_scan_enabled
= false;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>while
(z[0] != 0 && z[0] != ' ')</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>z++;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>while
(z[0] == ' ')</div>
<div>diff --git a/src/box/sql/func.c b/src/box/sql/func.c</div>
<div>index 66cae17b5..28b435ae3 100644</div>
<div>--- a/src/box/sql/func.c</div>
<div>+++ b/src/box/sql/func.c</div>
<div>@@ -607,41 +607,38 @@ total_changes(sqlite3_context *
context, int NotUsed, sqlite3_value ** NotUsed2)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_int(context,
sqlite3_total_changes(db));</div>
<div> }</div>
<div> </div>
<div>-/*</div>
<div>- * A structure defining how to do GLOB-style
comparisons.</div>
<div>- */</div>
<div>-struct compareInfo {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>u8
matchAll;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
"*" or "%" */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>u8
matchOne;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
"?" or "_" */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>u8
matchSet;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
"[" or 0 */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>u8
noCase;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
true to ignore case differences */</div>
<div>-};</div>
<div>-</div>
<div> /**</div>
<div>- * Providing there are symbols in string s this</div>
<div>- * macro returns UTF-8 code of character and</div>
<div>- * promotes pointer to the next symbol in the string.</div>
<div>- * Otherwise return code is SQL_END_OF_STRING.</div>
<div>+ * Providing there are symbols in string s this macro
returns</div>
<div>+ * UTF-8 code of character and promotes pointer to the
next</div>
<div>+ * symbol in the string. If s points to an invalid UTF-8
symbol</div>
<div>+ * return code is SQL_INVALID_UTF8_SYMBOL. If there're
no symbols</div>
<div>+ * left in string s return code is SQL_END_OF_STRING.</div>
<div> */</div>
<div> #define Utf8Read(s, e) ucnv_getNextUChar(pUtf8conv,
&(s), (e), &(status))</div>
<div> </div>
<div> #define SQL_END_OF_STRING 0xffff</div>
<div> #define SQL_INVALID_UTF8_SYMBOL 0xfffd</div>
<div> </div>
<div>-static const struct compareInfo globInfo = { '*', '?',
'[', 0 };</div>
<div>+/**</div>
<div>+ * If SQLITE_CASE_SENSITIVE_LIKE is not defined, then
the LIKE</div>
<div>+ * operator is not case sensitive.</div>
<div>+ */</div>
<div>+static const int case_insensitive_like = 1;</div>
<div> </div>
<div>-/* The correct SQL-92 behavior is for the LIKE operator
to ignore</div>
<div>- * case. Thus 'a' LIKE 'A' would be true.</div>
<div>+/**</div>
<div>+ * If SQLITE_CASE_SENSITIVE_LIKE is defined, then the
LIKE</div>
<div>+ * operator is case sensitive causing 'a' LIKE 'A' to be
false.</div>
<div> */</div>
<div>-static const struct compareInfo likeInfoNorm = { '%',
'_', 0, 1 };</div>
<div>+static const int case_sensitive_like = 0;</div>
<div> </div>
<div>-/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the
LIKE operator</div>
<div>- * is case sensitive causing 'a' LIKE 'A' to be false</div>
<div>+/**</div>
<div>+ * Wildcards.</div>
<div> */</div>
<div>-static const struct compareInfo likeInfoAlt = { '%',
'_', 0, 0 };</div>
<div>+#define match_one '_'</div>
<div>+#define match_all '%'</div>
<div> </div>
<div>-/*</div>
<div>- * Possible error returns from
sql_utf8_pattern_compare()</div>
<div>+/**</div>
<div>+ * Possible error returns from
sql_utf8_pattern_compare().</div>
<div> */</div>
<div> #define SQL_MATCH 0</div>
<div> #define SQL_NOMATCH 1</div>
<div>@@ -650,138 +647,91 @@ static const struct compareInfo
likeInfoAlt = { '%', '_', 0, 0 };</div>
<div> </div>
<div> /**</div>
<div> * Compare two UTF-8 strings for equality where the
first string</div>
<div>- * is a GLOB or LIKE expression.</div>
<div>- *</div>
<div>- * Globbing rules:</div>
<div>- *</div>
<div>- * '*' Matches any sequence of zero or more
characters.</div>
<div>- *</div>
<div>- * '?' Matches exactly one character.</div>
<div>- *</div>
<div>- * [...] Matches one character from the
enclosed list of</div>
<div>- * characters.</div>
<div>- *</div>
<div>- * [^...] Matches one character not in the
enclosed list.</div>
<div>- *</div>
<div>- * With the [...] and [^...] matching, a ']' character
can be</div>
<div>- * included in the list by making it the first character
after</div>
<div>- * '[' or '^'. A range of characters can be specified
using '-'.</div>
<div>- * Example: "[a-z]" matches any single lower-case
letter.</div>
<div>- * To match a '-', make it the last character in the
list.</div>
<div>+ * is a LIKE expression.</div>
<div> *</div>
<div> * Like matching rules:</div>
<div> *</div>
<div>- * '%' Matches any sequence of zero or more
characters.</div>
<div>+ * '%' Matches any sequence of zero or more</div>
<div>+ * characters.</div>
<div> *</div>
<div> * '_' Matches any one character.</div>
<div> *</div>
<div>- * Ec Where E is the "esc" character and c
is any other</div>
<div>- * character, including '%', '_', and
esc, match</div>
<div>- * exactly c.</div>
<div>- *</div>
<div>- * The comments within this routine usually assume glob
matching.</div>
<div>+ * Ec Where E is the "esc" character and c
is any</div>
<div>+ * other character, including '%', '_',
and esc,</div>
<div>+ * match exactly c.</div>
<div> *</div>
<div> * This routine is usually quick, but can be N**2 in the
worst</div>
<div> * case.</div>
<div> *</div>
<div> * @param pattern String containing comparison pattern.</div>
<div> * @param string String being compared.</div>
<div>- * @param compareInfo Information about how to compare.</div>
<div>- * @param matchOther The escape char (LIKE) or '['
(GLOB).</div>
<div>+ * @param is_like_ci true if LIKE is case insensitive.</div>
<div>+ * @param match_other The escape char for LIKE.</div>
<div> *</div>
<div> * @retval SQL_MATCH: Match.</div>
<div> *<span class="Apple-tab-span" style="white-space:pre"> </span>
SQL_NOMATCH: No match.</div>
<div>- *<span class="Apple-tab-span" style="white-space:pre"> </span>
SQL_NOWILDCARDMATCH: No match in spite of having *</div>
<div>- *<span class="Apple-tab-span" style="white-space:pre"> </span>
or % wildcards.</div>
<div>+ *<span class="Apple-tab-span" style="white-space:pre"> </span>
SQL_NOWILDCARDMATCH: No match in spite of having %</div>
<div>+ *<span class="Apple-tab-span" style="white-space:pre"> </span>
wildcard.</div>
<div> *<span class="Apple-tab-span" style="white-space:pre"> </span>
SQL_INVALID_PATTERN: Pattern contains invalid</div>
<div> *<span class="Apple-tab-span" style="white-space:pre"> </span>
symbol.</div>
<div> */</div>
<div> static int</div>
<div> sql_utf8_pattern_compare(const char *pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
const char *string,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
const struct compareInfo *pInfo,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
UChar32 matchOther)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
const int is_like_ci,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
UChar32 match_other)</div>
<div> {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/*
Next pattern and input string chars */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>UChar32
c, c2;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
"?" or "_" */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>UChar32
matchOne = pInfo->matchOne;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
"*" or "%" */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>UChar32
matchAll = pInfo->matchAll;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
True if uppercase==lowercase */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>UChar32
noCase = pInfo->noCase;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/*
One past the last escaped input char */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>const
char *zEscaped = 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>const
char * pattern_end = pattern + strlen(pattern);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>const
char * string_end = string + strlen(string);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>const
char *pattern_end = pattern + strlen(pattern);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>const
char *string_end = string + strlen(string);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>UErrorCode
status = U_ZERO_ERROR;</div>
<div> </div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>while
(pattern < pattern_end) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(pattern, pattern_end);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == matchAll) {<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Match "*" */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Skip over multiple "*" characters in</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* the pattern. If there are also "?"</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == match_all) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* Skip over multiple "%" characters in</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* the pattern. If there are also "_"</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* characters, skip those as well, but</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* consume a single character of the</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* input string for each "?" skipped.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* input string for each "_" skipped.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>while
((c = Utf8Read(pattern, pattern_end)) !=</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
SQL_END_OF_STRING) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c != matchAll && c != matchOne)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c != match_all && c != match_one)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>break;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == matchOne &&</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == match_one &&</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
(c2 = Utf8Read(string, string_end)) ==</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
SQL_END_OF_STRING)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOWILDCARDMATCH;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* "*" at the end of the pattern matches.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* "%" at the end of the pattern matches.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_END_OF_STRING) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_MATCH;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == matchOther) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(pInfo->matchSet == 0) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_END_OF_STRING)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOWILDCARDMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}
else {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
"[...]" immediately</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* follows the "*". We</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* have to do a slow</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* recursive search in</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* this case, but it is</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* an unusual case.</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>assert(matchOther
< 0x80);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>while
(string < string_end) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
bMatch =</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
sql_utf8_pattern_compare(</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>&pattern[-1],</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>string,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>pInfo,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>matchOther);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(bMatch != SQL_NOMATCH)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
bMatch;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(string, string_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == match_other) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(pattern, pattern_end);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_END_OF_STRING)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOWILDCARDMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> </div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
At this point variable c contains the</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* At this point variable c contains the</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* first character of the pattern string</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* past the "*". Search in the input</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* past the "%". Search in the input</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* string for the first matching</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* character and recursively continue the</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* match from that point.</div>
<div>@@ -793,7 +743,7 @@ sql_utf8_pattern_compare(const char
*pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> </div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>int
bMatch;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(noCase)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(is_like_ci)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>c
= u_tolower(c);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>while
(string < string_end){</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>@@ -809,7 +759,7 @@ sql_utf8_pattern_compare(const char
*pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(string, string_end);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(!noCase) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(!is_like_ci) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 != c)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}
else {</div>
<div>@@ -818,79 +768,27 @@ sql_utf8_pattern_compare(const char
*pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>bMatch
= sql_utf8_pattern_compare(pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
string,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
pInfo,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
matchOther);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
is_like_ci,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
match_other);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(bMatch != SQL_NOMATCH)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
bMatch;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOWILDCARDMATCH;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == matchOther) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(pInfo->matchSet == 0) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_END_OF_STRING)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>zEscaped
= pattern;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}
else {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>UChar32
prior_c = 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
seen = 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
invert = 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(string, string_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(string == string_end)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == '^') {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>invert
= 1;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == ']') {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == ']')</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>seen
= 1;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>while
(c2 != SQL_END_OF_STRING && c2 != ']') {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == '-' && pattern[0] != ']'</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
&& pattern < pattern_end</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
&& prior_c > 0) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c >= prior_c && c <= c2)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>seen
= 1;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>prior_c
= 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}
else {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == c2) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>seen
= 1;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>prior_c
= c2;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(pattern, pattern_end);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(pattern == pattern_end ||</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
(seen ^ invert) == 0) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == match_other) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>c
= Utf8Read(pattern, pattern_end);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_INVALID_UTF8_SYMBOL)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_INVALID_PATTERN;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == SQL_END_OF_STRING)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>zEscaped
= pattern;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>c2
= Utf8Read(string, string_end);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c2 == SQL_INVALID_UTF8_SYMBOL)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == c2)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(noCase){</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(is_like_ci) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* Small optimisation. Reduce number of</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* calls to u_tolower function. SQL</div>
<div>@@ -903,7 +801,7 @@ sql_utf8_pattern_compare(const char
*pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
c == u_tolower(c2))</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == matchOne && pattern != zEscaped &&</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(c == match_one && pattern != zEscaped &&</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
c2 != SQL_END_OF_STRING)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>continue;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
SQL_NOMATCH;</div>
<div>@@ -911,55 +809,52 @@ sql_utf8_pattern_compare(const char
*pattern,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
string == string_end ? SQL_MATCH : SQL_NOMATCH;</div>
<div> }</div>
<div> </div>
<div>-/*</div>
<div>- * The sqlite3_strglob() interface. Return 0 on a match
(like strcmp()) and</div>
<div>- * non-zero if there is no match.</div>
<div>+/**</div>
<div>+ * Compare two UTF-8 strings for equality using case
sensitive</div>
<div>+ * sql_utf8_pattern_compare.</div>
<div> */</div>
<div> int</div>
<div>-sqlite3_strglob(const char *zGlobPattern, const char
*zString)</div>
<div>+sql_strlike_cs(const char *zPattern, const char *zStr,
unsigned int esc)</div>
<div> {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
sql_utf8_pattern_compare(zGlobPattern, zString,
&globInfo, '[');</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>return
sql_utf8_pattern_compare(zPattern, zStr,
case_sensitive_like, esc);</div>
<div> }</div>
<div> </div>
<div>-/*</div>
<div>- * The sqlite3_strlike() interface. Return 0 on a match
and non-zero for</div>
<div>- * a miss - like strcmp().</div>
<div>+/**</div>
<div>+ * Compare two UTF-8 strings for equality using case
insensitive</div>
<div>+ * sql_utf8_pattern_compare.</div>
<div> */</div>
<div> int</div>
<div>-sqlite3_strlike(const char *zPattern, const char *zStr,
unsigned int esc)</div>
<div>+sql_strlike_ci(const char *zPattern, const char *zStr,
unsigned int esc)</div>
<div> {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>return
sql_utf8_pattern_compare(zPattern, zStr, &likeInfoNorm,
esc);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>return
sql_utf8_pattern_compare(zPattern, zStr,
case_insensitive_like, esc);</div>
<div> }</div>
<div> </div>
<div>-/*</div>
<div>- * Count the number of times that the LIKE operator (or
GLOB which is</div>
<div>- * just a variation of LIKE) gets called. This is used
for testing</div>
<div>- * only.</div>
<div>+/**</div>
<div>+ * Count the number of times that the LIKE operator gets
called.</div>
<div>+ * This is used for testing only.</div>
<div> */</div>
<div> #ifdef SQLITE_TEST</div>
<div> int sqlite3_like_count = 0;</div>
<div> #endif</div>
<div> </div>
<div>-/*</div>
<div>- * Implementation of the like() SQL function. This
function implements</div>
<div>- * the build-in LIKE operator. The first argument to
the function is the</div>
<div>- * pattern and the second argument is the string. So,
the SQL statements:</div>
<div>+/**</div>
<div>+ * Implementation of the like() SQL function. This
function</div>
<div>+ * implements the built-in LIKE operator. The first
argument to</div>
<div>+ * the function is the pattern and the second argument
is the</div>
<div>+ * string. So, the SQL statements of the following type:</div>
<div> *</div>
<div> * A LIKE B</div>
<div> *</div>
<div>- * is implemented as like(B,A).</div>
<div>- *</div>
<div>- * This same function (with a different compareInfo
structure) computes</div>
<div>- * the GLOB operator.</div>
<div>+ * are implemented as like(B,A).</div>
<div> */</div>
<div> static void</div>
<div>-likeFunc(sqlite3_context * context, int argc,
sqlite3_value ** argv)</div>
<div>+likeFunc(sqlite3_context *context, int argc,
sqlite3_value **argv)</div>
<div> {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>const
char *zA, *zB;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>u32
escape;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>int
nPat;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3
*db = sqlite3_context_db_handle(context);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>struct
compareInfo *pInfo = sqlite3_user_data(context);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
*is_like_ci = sqlite3_user_data(context);</div>
<div> </div>
<div> #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(sqlite3_value_type(argv[0]) == SQLITE_BLOB</div>
<div>@@ -974,8 +869,9 @@ likeFunc(sqlite3_context * context,
int argc, sqlite3_value ** argv)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>zB
= (const char *) sqlite3_value_text(argv[0]);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>zA
= (const char *) sqlite3_value_text(argv[1]);</div>
<div> </div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Limit the length of the LIKE or GLOB pattern to avoid</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* problems of deep recursion and N*N behavior in</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* Limit the length of the LIKE pattern to avoid problems</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* of deep recursion and N*N behavior in</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* sql_utf8_pattern_compare().</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>nPat
= sqlite3_value_bytes(argv[0]);</div>
<div>@@ -983,28 +879,29 @@ likeFunc(sqlite3_context * context,
int argc, sqlite3_value ** argv)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>testcase(nPat
== db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] + 1);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH])
{</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
"LIKE or GLOB pattern too complex", -1);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
"LIKE pattern is too complex", -1);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/*
Encoding did not change */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>assert(zB
== (const char *) sqlite3_value_text(argv[0]));</div>
<div> </div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(argc == 3) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
The escape character string must consist of a single UTF-8
character.</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* Otherwise, return an error.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* The escape character string must consist of a</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* single UTF-8 character. Otherwise, return an</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* error.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>const
unsigned char *zEsc = sqlite3_value_text(argv[2]);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(zEsc == 0)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(sqlite3Utf8CharLen((char *)zEsc, -1) != 1) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
"ESCAPE expression must be a single character",</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
"ESCAPE expression must be a"</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
" single character",</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
-1);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>escape
= sqlite3Utf8Read(&zEsc);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}
else {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>escape
= pInfo->matchSet;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(!zA || !zB)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div>@@ -1012,10 +909,10 @@ likeFunc(sqlite3_context *
context, int argc, sqlite3_value ** argv)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_like_count++;</div>
<div> #endif</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>int
res;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>res
= sql_utf8_pattern_compare(zB, zA, pInfo, escape);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>res
= sql_utf8_pattern_compare(zB, zA, *is_like_ci, escape);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(res == SQL_INVALID_PATTERN) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context,
"LIKE or GLOB pattern can only"</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
" contain UTF-8 characters", -1);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_error(context,
"LIKE pattern can only contain"</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
" UTF-8 characters", -1);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_result_int(context,
res == SQL_MATCH);</div>
<div>@@ -1811,64 +1708,54 @@ setLikeOptFlag(sqlite3 * db,
const char *zName, u8 flagVal)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> }</div>
<div> </div>
<div>-/*</div>
<div>- * Register the built-in LIKE and GLOB functions. The
caseSensitive</div>
<div>- * parameter determines whether or not the LIKE operator
is case</div>
<div>- * sensitive. GLOB is always case sensitive.</div>
<div>+/**</div>
<div>+ * Register the built-in LIKE function.</div>
<div>+ *</div>
<div>+ * @param db database structure.</div>
<div>+ * @param is_case_sensitive whether like should be case
sensitive</div>
<div>+ * <span class="Apple-tab-span" style="white-space:pre"> </span>
or not.</div>
<div>+ *</div>
<div>+ * @retval none.</div>
<div> */</div>
<div> void</div>
<div>-sqlite3RegisterLikeFunctions(sqlite3 * db, int
caseSensitive)</div>
<div>+sqlite3RegisterLikeFunctions(sqlite3 *db, int
is_case_sensitive)</div>
<div> {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>struct
compareInfo *pInfo;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(caseSensitive) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>pInfo
= (struct compareInfo *)&likeInfoAlt;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}
else {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>pInfo
= (struct compareInfo *)&likeInfoNorm;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3CreateFunc(db,
"LIKE", 2, 0, pInfo, likeFunc, 0, 0, 0);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3CreateFunc(db,
"LIKE", 3, 0, pInfo, likeFunc, 0, 0, 0);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3CreateFunc(db,
"GLOB", 2, 0, (struct compareInfo *)&globInfo, likeFunc,
0, 0, 0);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>setLikeOptFlag(db,
"GLOB", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
*is_like_ci;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(is_case_sensitive)</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>is_like_ci
= (int *)&case_sensitive_like;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>else</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>is_like_ci
= (int *)&case_insensitive_like;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3CreateFunc(db,
"LIKE", 2, 0, is_like_ci, likeFunc, 0, 0, 0);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3CreateFunc(db,
"LIKE", 3, 0, is_like_ci, likeFunc, 0, 0, 0);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>setLikeOptFlag(db,
"LIKE",</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE)
:</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
SQLITE_FUNC_LIKE);</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
is_case_sensitive ? (SQLITE_FUNC_LIKE |</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);</div>
<div> }</div>
<div> </div>
<div>-/*</div>
<div>- * pExpr points to an expression which implements a
function. If</div>
<div>- * it is appropriate to apply the LIKE optimization to
that function</div>
<div>- * then set aWc[0] through aWc[2] to the wildcard
characters and</div>
<div>- * return TRUE. If the function is not a LIKE-style
function then</div>
<div>- * return FALSE.</div>
<div>+/**</div>
<div>+ * Check if the function implements LIKE-style
comparison & if it</div>
<div>+ * is appropriate to apply a LIKE query optimization.</div>
<div>+ *</div>
<div>+ * @param db database structure.</div>
<div>+ * @param pExpr pointer to a function-implementing
expression.</div>
<div>+ * @param is_like_ci true if LIKE is case insensitive.</div>
<div> *</div>
<div>- * *pIsNocase is set to true if uppercase and lowercase
are equivalent for</div>
<div>- * the function (default for LIKE). If the function
makes the distinction</div>
<div>- * between uppercase and lowercase (as does GLOB) then
*pIsNocase is set to</div>
<div>- * false.</div>
<div>+ * @retval 0 if it's appropriate to apply optimization.</div>
<div>+ * 1 if it's not.</div>
<div> */</div>
<div> int</div>
<div>-sqlite3IsLikeFunction(sqlite3 * db, Expr * pExpr, int
*pIsNocase, char *aWc)</div>
<div>+sql_is_like_func(sqlite3 *db, Expr *pExpr, int
*is_like_ci)</div>
<div> {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>FuncDef
*pDef;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(pExpr->op != TK_FUNCTION</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
|| !pExpr->x.pList || pExpr->x.pList->nExpr !=
2) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(pExpr->op != TK_FUNCTION || !pExpr->x.pList ||</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
pExpr->x.pList->nExpr != 2)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>assert(!ExprHasProperty(pExpr,
EP_xIsSelect));</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>pDef
= sqlite3FindFunction(db, pExpr->u.zToken, 2, 0);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(NEVER(pDef == 0) || (pDef->funcFlags &
SQLITE_FUNC_LIKE) == 0) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
0;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>-</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
The memcpy() statement assumes that the wildcard characters
are</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* the first three statements in the compareInfo structure.
The</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* asserts() that follow verify that assumption</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>memcpy(aWc,
pDef->pUserData, 3);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>assert((char
*)&likeInfoAlt == (char *)&likeInfoAlt.matchAll);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>assert(&((char
*)&likeInfoAlt)[1] == (char
*)&likeInfoAlt.matchOne);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>assert(&((char
*)&likeInfoAlt)[2] == (char
*)&likeInfoAlt.matchSet);</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>*pIsNocase
= (pDef->funcFlags & SQLITE_FUNC_CASE) == 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>*is_like_ci
= (pDef->funcFlags & SQLITE_FUNC_CASE) == 0;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
1;</div>
<div> }</div>
<div> </div>
<div>@@ -1962,16 +1849,14 @@
sqlite3RegisterBuiltinFunctions(void)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>AGGREGATE(group_concat,
2, 0, 0, groupConcatStep,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
groupConcatFinalize),</div>
<div> </div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(glob,
2, &globInfo,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE),</div>
<div> #ifdef SQLITE_CASE_SENSITIVE_LIKE</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
2, &likeInfoAlt,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
2, &case_sensitive_like,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE),</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
3, &likeInfoAlt,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
3, &case_sensitive_like,</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE),</div>
<div> #else</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
2, &likeInfoNorm, SQLITE_FUNC_LIKE),</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
3, &likeInfoNorm, SQLITE_FUNC_LIKE),</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
2, &case_insensitive_like, SQLITE_FUNC_LIKE),</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>LIKEFUNC(like,
3, &case_insensitive_like, SQLITE_FUNC_LIKE),</div>
<div> #endif</div>
<div> #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>FUNCTION(unknown,
-1, 0, 0, unknownFunc),</div>
<div>diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c</div>
<div>index 5fb29c75c..26a602b23 100644</div>
<div>--- a/src/box/sql/pragma.c</div>
<div>+++ b/src/box/sql/pragma.c</div>
<div>@@ -771,8 +771,10 @@ sqlite3Pragma(Parse * pParse, Token
* pId,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
First part of [schema.]id field */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> #endif</div>
<div> </div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Reinstall the LIKE and GLOB functions. The variant of LIKE
*</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* used will be case sensitive or not depending on the RHS.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* Reinstall the LIKE and functions. The variant</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* of LIKE * used will be case sensitive or not</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* depending on the RHS.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>case
PragTyp_CASE_SENSITIVE_LIKE:{</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(zRight) {</div>
<div>diff --git a/src/box/sql/sqliteInt.h
b/src/box/sql/sqliteInt.h</div>
<div>index e7a02dc1d..a805adf22 100644</div>
<div>--- a/src/box/sql/sqliteInt.h</div>
<div>+++ b/src/box/sql/sqliteInt.h</div>
<div>@@ -565,16 +565,15 @@ char *</div>
<div> sqlite3_vsnprintf(int, char *, const char *, va_list);</div>
<div> </div>
<div> int</div>
<div>-sqlite3_strlike(const char *zGlob, const char *zStr,</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>unsigned
int cEsc);</div>
<div>+sql_strlike_cs(const char *zLike, const char *zStr,
unsigned int cEsc);</div>
<div>+</div>
<div>+int</div>
<div>+sql_strlike_ci(const char *zLike, const char *zStr,
unsigned int cEsc);</div>
<div> </div>
<div> typedef void (*sqlite3_destructor_type) (void *);</div>
<div> #define SQLITE_STATIC ((sqlite3_destructor_type)0)</div>
<div> #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)</div>
<div> </div>
<div>-int</div>
<div>-sqlite3_strglob(const char *zGlob, const char *zStr);</div>
<div>-</div>
<div> int</div>
<div> sqlite3_prepare(sqlite3 * db,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Database handle */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>const
char *zSql,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
SQL statement, UTF-8 encoded */</div>
<div>@@ -701,9 +700,6 @@ struct on_conflict {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>enum
on_conflict_action optimized_action;</div>
<div> };</div>
<div> </div>
<div>-void *</div>
<div>-sqlite3_user_data(sqlite3_context *);</div>
<div>-</div>
<div> void</div>
<div> sqlite3_randomness(int N, void *P);</div>
<div> </div>
<div>@@ -2355,7 +2351,7 @@ struct Expr {</div>
<div> #define EP_Distinct 0x000010<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Aggregate function with DISTINCT keyword */</div>
<div> #define EP_VarSelect 0x000020<span class="Apple-tab-span" style="white-space:pre"> </span>/*
pSelect is correlated, not constant */</div>
<div> #define EP_DblQuoted 0x000040<span class="Apple-tab-span" style="white-space:pre"> </span>/*
token.z was originally in "..." */</div>
<div>-#define EP_InfixFunc 0x000080<span class="Apple-tab-span" style="white-space:pre"> </span>/*
True for an infix function: LIKE, GLOB, etc */</div>
<div>+#define EP_InfixFunc 0x000080<span class="Apple-tab-span" style="white-space:pre"> </span>/*
True for an infix function: LIKE, etc */</div>
<div> #define EP_Collate 0x000100<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Tree contains a TK_COLLATE operator */</div>
<div> #define EP_Generic 0x000200<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Ignore COLLATE or affinity on this tree */</div>
<div> #define EP_IntValue 0x000400<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Integer value contained in u.iValue */</div>
<div>@@ -4378,7 +4374,7 @@ index_column_count(const Index *);</div>
<div> bool</div>
<div> index_is_unique_not_null(const Index *);</div>
<div> void sqlite3RegisterLikeFunctions(sqlite3 *, int);</div>
<div>-int sqlite3IsLikeFunction(sqlite3 *, Expr *, int *, char
*);</div>
<div>+int sql_is_like_func(sqlite3 *db, Expr *pExpr, int
*is_case_insensitive);</div>
<div> void sqlite3SchemaClear(sqlite3 *);</div>
<div> Schema *sqlite3SchemaCreate(sqlite3 *);</div>
<div> int sqlite3CreateFunc(sqlite3 *, const char *, int, int,
void *,</div>
<div>diff --git a/src/box/sql/sqliteLimit.h
b/src/box/sql/sqliteLimit.h</div>
<div>index b88c9c6d3..e76353aff 100644</div>
<div>--- a/src/box/sql/sqliteLimit.h</div>
<div>+++ b/src/box/sql/sqliteLimit.h</div>
<div>@@ -164,8 +164,7 @@ enum {</div>
<div> #endif</div>
<div> </div>
<div> /*</div>
<div>- * Maximum length (in bytes) of the pattern in a LIKE or
GLOB</div>
<div>- * operator.</div>
<div>+ * Maximum length (in bytes) of the pattern in a LIKE
operator.</div>
<div> */</div>
<div> #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH</div>
<div> #define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000</div>
<div>diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c</div>
<div>index 0c978142d..3f10f4d68 100644</div>
<div>--- a/src/box/sql/vdbe.c</div>
<div>+++ b/src/box/sql/vdbe.c</div>
<div>@@ -5521,7 +5521,7 @@ vdbe_return:</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>testcase(
nVmStep>0);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>p->aCounter[SQLITE_STMTSTATUS_VM_STEP]
+= (int)nVmStep;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>assert(rc!=SQLITE_OK
|| nExtraDelete==0</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>||
sqlite3_strlike("DELETE%",p->zSql,0)!=0</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>||
sql_strlike_ci("DELETE%", p->zSql, 0) != 0</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
rc;</div>
<div> </div>
<div>diff --git a/src/box/sql/wherecode.c
b/src/box/sql/wherecode.c</div>
<div>index c35c25ac4..f864ea7fa 100644</div>
<div>--- a/src/box/sql/wherecode.c</div>
<div>+++ b/src/box/sql/wherecode.c</div>
<div>@@ -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> * automatically disabled. In this way, terms get
disabled if derived</div>
<div> * virtual terms are tested first. For example:</div>
<div> *</div>
<div>- * x GLOB 'abc*' AND x>='abc' AND x<'acd'</div>
<div>+ * x LIKE 'abc%' AND x>='abc' AND x<'acd'</div>
<div> * \___________/ \______/ \_____/</div>
<div> * parent child1 child2</div>
<div> *</div>
<div>diff --git a/src/box/sql/whereexpr.c
b/src/box/sql/whereexpr.c</div>
<div>index 612868695..2d9fb6453 100644</div>
<div>--- a/src/box/sql/whereexpr.c</div>
<div>+++ b/src/box/sql/whereexpr.c</div>
<div>@@ -218,38 +218,61 @@ operatorMask(int op)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
c;</div>
<div> }</div>
<div> </div>
<div>+/**</div>
<div>+ * Wildcard characters.</div>
<div>+ */</div>
<div>+#define match_one '_'</div>
<div>+#define match_all '%'</div>
</div>
</div>
</blockquote>
If possible - move the define to a header which both (whereexpr and
func) file include.<br>
This also require to give more descriptive name, e.g.
LIKE_MATCH_ONE.<br>
<blockquote type="cite"
cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org">
<div class="">
<div>
<div>+</div>
<div> #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION</div>
<div>-/*</div>
<div>- * Check to see if the given expression is a LIKE or
GLOB operator that</div>
<div>- * can be optimized using inequality constraints.
Return TRUE if it is</div>
<div>- * so and false if not.</div>
<div>+/**</div>
<div>+ * Check to see if the given expression is a LIKE
operator that</div>
<div>+ * can be optimized using inequality constraints.</div>
<div> *</div>
<div>- * In order for the operator to be optimizible, the RHS
must be a string</div>
<div>- * literal that does not begin with a wildcard. The LHS
must be a column</div>
<div>- * that may only be NULL, a string, or a BLOB, never a
number. The</div>
<div>- * collating sequence for the column on the LHS must be
appropriate for</div>
<div>- * the operator.</div>
<div>+ * In order for the operator to be optimizible, the RHS
must be a</div>
<div>+ * string literal that does not begin with a wildcard.
The LHS</div>
<div>+ * must be a column that may only be NULL, a string, or
a BLOB,</div>
<div>+ * never a number. The collating sequence for the column
on the</div>
<div>+ * LHS must be appropriate for the operator.</div>
<div>+ *</div>
<div>+ * @param pParse Parsing and code generating
context.</div>
<div>+ * @param pExpr Test this expression.</div>
<div>+ * @param ppPrefix Pointer to TK_STRING expression
with</div>
<div>+ *<span class="Apple-tab-span" style="white-space:pre"> </span>
pattern prefix.</div>
<div>+ * @param pisComplete True if the only wildcard is '%'
in the</div>
<div>+ * <span class="Apple-tab-span" style="white-space:pre"> </span>
last character.</div>
<div>+ * @param pnoCase True if case insensitive.</div>
<div>+ *</div>
<div>+ * @retval True if the given expr is a LIKE operator
& is</div>
<div>+ *<span class="Apple-tab-span" style="white-space:pre"> </span>
optimizable using inequality constraints.</div>
<div>+ * <span class="Apple-tab-span" style="white-space:pre"> </span>
False if not.</div>
<div> */</div>
<div> static int</div>
<div>-isLikeOrGlob(Parse * pParse,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Parsing and code generating context */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
Expr * pExpr,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Test this expression */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
Expr ** ppPrefix,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Pointer to TK_STRING expression with pattern prefix */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
int *pisComplete,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
True if the only wildcard is % in the last character */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
int *pnoCase<span class="Apple-tab-span" style="white-space:pre"> </span>/*
True if uppercase is equivalent to lowercase */</div>
<div>- )</div>
<div>+is_like(Parse *pParse,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pExpr,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
**ppPrefix,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
*pisComplete,</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
*pnoCase)</div>
<div> {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>const
char *z = 0;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
String on RHS of LIKE operator */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pRight, *pLeft;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Right and left size of LIKE operator */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>ExprList
*pList;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
List of operands to the LIKE operator */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
c;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
One character in z[] */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
cnt;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Number of non-wildcard prefix characters */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>char
wc[3];<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Wildcard characters */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3
*db = pParse->db;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Database connection */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
String on RHS of LIKE operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>const
char *z = 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Right and left size of LIKE operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pRight, *pLeft;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
List of operands to the LIKE operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>ExprList
*pList;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
One character in z[] */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
c;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Number of non-wildcard prefix characters */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
cnt;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Database connection */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3
*db = pParse->db;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3_value
*pVal = 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
op;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Opcode of pRight */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
rc;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Result code to return */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Opcode of pRight */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
op;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Result code to return */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
rc;</div>
<div> </div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if
(!sqlite3IsLikeFunction(db, pExpr, pnoCase, wc)) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if
(!sql_is_like_func(db, pExpr, pnoCase)) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
0;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>pList
= pExpr->x.pList;</div>
<div>@@ -257,8 +280,9 @@ isLikeOrGlob(Parse * pParse,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Parsing and code generating context */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>/*
Value might be numeric */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(pLeft->op != TK_COLUMN ||</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
sqlite3ExprAffinity(pLeft) != AFFINITY_TEXT) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
IMP: R-02065-49465 The left-hand side of the LIKE or GLOB
operator must</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* be the name of an indexed column with TEXT affinity.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
IMP: R-02065-49465 The left-hand side of the</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* LIKE operator must be the name of an indexed</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* column with TEXT affinity.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return
0;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div>@@ -281,13 +305,11 @@ isLikeOrGlob(Parse * pParse,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Parsing and code generating context */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(z) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>cnt
= 0;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>while
((c = z[cnt]) != 0 && c != wc[0] && c !=
wc[1]</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
&& c != wc[2]) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>while
((c = z[cnt]) != 0 && c != match_one && c !=
match_all)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>cnt++;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(cnt != 0 && 255 != (u8) z[cnt - 1]) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pPrefix;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>*pisComplete
= c == wc[0] && z[cnt + 1] == 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>*pisComplete
= c == match_all && z[cnt + 1] == 0;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>pPrefix
= sqlite3Expr(db, TK_STRING, z);</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(pPrefix)</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>pPrefix->u.zToken[cnt]
= 0;</div>
<div>@@ -943,19 +965,32 @@ exprAnalyze(SrcList * pSrc,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
the FROM clause */</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
int idxTerm<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Index of the term to be analyzed */</div>
<div> )</div>
<div> {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>WhereInfo
*pWInfo = pWC->pWInfo;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
WHERE clause processing context */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>WhereTerm
*pTerm;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
The term to be analyzed */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>WhereMaskSet
*pMaskSet;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Set of table index masks */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pExpr;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
The expression to be analyzed */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Bitmask
prereqLeft;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Prerequesites of the pExpr->pLeft */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Bitmask
prereqAll;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Prerequesites of pExpr */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Bitmask
extraRight = 0;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Extra dependencies on LEFT JOIN */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pStr1 = 0;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
RHS of LIKE/GLOB operator */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
isComplete = 0;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
RHS of LIKE/GLOB ends with wildcard */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
noCase = 0;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
uppercase equivalent to lowercase */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>int
op;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Top-level operator. pExpr->op */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Parse
*pParse = pWInfo->pParse;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Parsing context */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3
*db = pParse->db;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Database connection */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
WHERE clause processing context */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>WhereInfo
*pWInfo = pWC->pWInfo;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
The term to be analyzed */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>WhereTerm
*pTerm;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Set of table index masks */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>WhereMaskSet
*pMaskSet;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
The expression to be analyzed */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pExpr;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Prerequesites of the pExpr->pLeft */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Bitmask
prereqLeft;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Prerequesites of pExpr */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Bitmask
prereqAll;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Extra dependencies on LEFT JOIN */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Bitmask
extraRight = 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
RHS of LIKE operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pStr1 = 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
RHS of LIKE ends with wildcard */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
isComplete = 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
uppercase equivalent to lowercase */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
noCase = 0;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Top-level operator. pExpr->op */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int
op;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Parsing context */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Parse
*pParse = pWInfo->pParse;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Database connection */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>sqlite3
*db = pParse->db;</div>
<div> </div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(db->mallocFailed) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>return;</div>
<div>@@ -1111,37 +1146,44 @@ exprAnalyze(SrcList * pSrc,<span class="Apple-tab-span" style="white-space:pre"> </span>/*
the FROM clause */</div>
<div> #endif<span class="Apple-tab-span" style="white-space:pre"> </span>/*
SQLITE_OMIT_OR_OPTIMIZATION */</div>
<div> </div>
<div> #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Add constraints to reduce the search space on a LIKE or GLOB</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* Add constraints to reduce the search space on a LIKE</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* operator.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* A like pattern of the form "x LIKE 'aBc%'" is changed into
constraints</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* A like pattern of the form "x LIKE 'aBc%'" is changed</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* into constraints:</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
* x>='ABC' AND x<'abd' AND x LIKE 'aBc%'</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* The last character of the prefix "abc" is incremented to
form the</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* termination condition "abd". If case is not significant
(the default</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* for LIKE) then the lower-bound is made all uppercase and
the upper-</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* bound is made all lowercase so that the bounds also work
when comparing</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* BLOBs.</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* The last character of the prefix "abc" is incremented</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* to form the termination condition "abd". If case is</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* not significant (the default for LIKE) then the</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* lower-bound is made all uppercase and the upper-bound</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* is made all lowercase so that the bounds also work</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* when comparing BLOBs.</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(pWC->op == TK_AND</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
&& isLikeOrGlob(pParse, pExpr, &pStr1,
&isComplete, &noCase)</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
) {</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pLeft;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
LHS of LIKE/GLOB operator */</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pStr2;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Copy of pStr1 - RHS of LIKE/GLOB operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
&& is_like(pParse, pExpr, &pStr1,
&isComplete, &noCase)) {</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
LHS of LIKE operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pLeft;</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Copy of pStr1 - RHS of LIKE operator */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pStr2;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pNewExpr1;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>Expr
*pNewExpr2;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>int
idxNew1;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>int
idxNew2;</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>const
char *zCollSeqName;<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Name of collating sequence */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Name of collating sequence */</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>const
char *zCollSeqName;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>const
u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;</div>
<div> </div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>pLeft
= pExpr->x.pList->a[1].pExpr;</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>pStr2
= sqlite3ExprDup(db, pStr1, 0);</div>
<div> </div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>/*
Convert the lower bound to upper-case and the upper bound to</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* lower-case (upper-case is less than lower-case in ASCII)
so that</div>
<div>-<span class="Apple-tab-span" style="white-space:pre"> </span>
* the range constraints also work for BLOBs</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>/**</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* Convert the lower bound to upper-case and the</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* upper bound to lower-case (upper-case is less</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* than lower-case in ASCII) so that the range</div>
<div>+<span class="Apple-tab-span" style="white-space:pre"> </span>
* constraints also work for BLOBs</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>
*/</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>if
(noCase && !pParse->db->mallocFailed) {</div>
<div> <span class="Apple-tab-span" style="white-space:pre"> </span>int
i;</div>
<div>diff --git a/test/sql-tap/alter.test.lua
b/test/sql-tap/alter.test.lua</div>
<div>index cfe280121..98338c493 100755</div>
<div>--- a/test/sql-tap/alter.test.lua</div>
<div>+++ b/test/sql-tap/alter.test.lua</div>
<div>@@ -232,7 +232,7 @@ test:do_execsql_test(</div>
<div> [[</div>
<div> CREATE TABLE xyz(x PRIMARY KEY);</div>
<div> ALTER TABLE xyz RENAME TO "xyz1234abc";</div>
<div>- SELECT "name" FROM "_space" WHERE "name" GLOB
'xyz*';</div>
<div>+ SELECT "name" FROM "_space" WHERE "name" =
'xyz1234abc';</div>
<div> ]], {</div>
<div> -- <alter-5.1></div>
<div> "xyz1234abc"</div>
<div>@@ -243,7 +243,7 @@ test:do_execsql_test(</div>
<div> "alter-5.2",</div>
<div> [[</div>
<div> ALTER TABLE "xyz1234abc" RENAME TO xyzabc;</div>
<div>- SELECT "name" FROM "_space" WHERE "name" GLOB
'XYZ*';</div>
<div>+ SELECT "name" FROM "_space" WHERE "name" =
'XYZABC';</div>
<div> ]], {</div>
<div> -- <alter-5.2></div>
<div> "XYZABC"</div>
<div>diff --git a/test/sql-tap/analyze9.test.lua
b/test/sql-tap/analyze9.test.lua</div>
<div>index 3b3d52f67..ec3e545d8 100755</div>
<div>--- a/test/sql-tap/analyze9.test.lua</div>
<div>+++ b/test/sql-tap/analyze9.test.lua</div>
<div>@@ -206,10 +206,10 @@ test:do_execsql_test(</div>
<div> INSERT INTO t1 VALUES(81, 1, 'one-i');</div>
<div> INSERT INTO t1 VALUES(91, 1, 'one-j');</div>
<div> INSERT INTO t1 SELECT a+1,2,'two' || substr(c,4)
FROM t1;</div>
<div>- INSERT INTO t1 SELECT a+2,3,'three'||substr(c,4)
FROM t1 WHERE c GLOB 'one-*';</div>
<div>- INSERT INTO t1 SELECT a+3,4,'four'||substr(c,4)
FROM t1 WHERE c GLOB 'one-*';</div>
<div>- INSERT INTO t1 SELECT a+4,5,'five'||substr(c,4)
FROM t1 WHERE c GLOB 'one-*';</div>
<div>- INSERT INTO t1 SELECT a+5,6,'six'||substr(c,4)
FROM t1 WHERE c GLOB 'one-*';<span class="Apple-tab-span" style="white-space:pre"> </span></div>
<div>+ INSERT INTO t1 SELECT a+2,3,'three'||substr(c,4)
FROM t1 WHERE c LIKE 'one-%';</div>
<div>+ INSERT INTO t1 SELECT a+3,4,'four'||substr(c,4)
FROM t1 WHERE c LIKE 'one-%';</div>
<div>+ INSERT INTO t1 SELECT a+4,5,'five'||substr(c,4)
FROM t1 WHERE c LIKE 'one-%';</div>
<div>+ INSERT INTO t1 SELECT a+5,6,'six'||substr(c,4)
FROM t1 WHERE c LIKE 'one-%';<span class="Apple-tab-span" style="white-space:pre"> </span></div>
<div> CREATE INDEX t1b ON t1(b);</div>
<div> ANALYZE;</div>
<div> SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND
60;</div>
<div>diff --git a/test/sql-tap/e_expr.test.lua
b/test/sql-tap/e_expr.test.lua</div>
<div>index 9780d2cf9..0d69e8535 100755</div>
<div>--- a/test/sql-tap/e_expr.test.lua</div>
<div>+++ b/test/sql-tap/e_expr.test.lua</div>
<div>@@ -1,6 +1,6 @@</div>
<div> #!/usr/bin/env tarantool</div>
<div> test = require("sqltester")</div>
<div>-test:plan(10665)</div>
<div>+test:plan(10647)</div>
<div> </div>
<div> --!./tcltestrunner.lua</div>
<div> -- 2010 July 16</div>
<div>@@ -77,10 +77,7 @@ local operations = {</div>
<div> {"<>", "ne1"},</div>
<div> {"!=", "ne2"},</div>
<div> {"IS", "is"},</div>
<div>--- NOTE: This test needs refactoring after deletion of
GLOB &</div>
<div>---<span class="Apple-tab-span" style="white-space:pre"> </span>
type restrictions for LIKE. (See #3572)</div>
<div> -- {"LIKE", "like"},</div>
<div>--- {"GLOB", "glob"},</div>
<div> {"AND", "and"},</div>
<div> {"OR", "or"},</div>
<div> {"MATCH", "match"},</div>
<div>@@ -98,12 +95,10 @@ operations = {</div>
<div> {"+", "-"},</div>
<div> {"<<", ">>", "&", "|"},</div>
<div> {"<", "<=", ">", ">="},</div>
<div>--- NOTE: This test needs refactoring after deletion of
GLOB &</div>
<div>---<span class="Apple-tab-span" style="white-space:pre"> </span>
type restrictions for LIKE. (See #3572)</div>
<div> -- Another NOTE: MATCH & REGEXP aren't supported in
Tarantool &</div>
<div>--- <span class="Apple-tab-span" style="white-space:pre"> </span>
are waiting for their hour, don't confuse them</div>
<div>---<span class="Apple-tab-span" style="white-space:pre"> </span>
being commented with ticket above.</div>
<div>- {"=", "==", "!=", "<>"}, --"LIKE", "GLOB"},
--"MATCH", "REGEXP"},</div>
<div>+-- are waiting for their hour, don't
confuse them</div>
<div>+-- being commented with commenting of
"LIKE".</div>
<div>+ {"=", "==", "!=", "<>"}, --"LIKE"}, --"MATCH",
"REGEXP"},</div>
<div> {"AND"},</div>
<div> {"OR"},</div>
<div> }</div>
<div>@@ -128,7 +123,7 @@ end</div>
<div> -- EVIDENCE-OF: R-15514-65163 SQLite understands the
following binary</div>
<div> -- operators, in order from highest to lowest
precedence: || * / % + -</div>
<div> -- << >> & | < <= > >= = ==
!= <> IS IS</div>
<div>--- NOT IN LIKE GLOB MATCH REGEXP AND OR</div>
<div>+-- NOT IN LIKE MATCH REGEXP AND OR</div>
<div> --</div>
<div> -- EVIDENCE-OF: R-38759-38789 Operators IS and IS NOT
have the same</div>
<div> -- precedence as =.</div>
<div>@@ -482,7 +477,6 @@ for _, op in ipairs(oplist) do</div>
<div> end</div>
<div> end</div>
<div> end</div>
<div>-</div>
<div> ---------------------------------------------------------------------------</div>
<div> -- Test the IS and IS NOT operators.</div>
<div> --</div>
<div>@@ -1303,11 +1297,11 @@ end</div>
<div> test:execsql [[</div>
<div> CREATE TABLE tblname(cname PRIMARY KEY);</div>
<div> ]]</div>
<div>+</div>
<div> local function glob(args)</div>
<div> return 1</div>
<div> end</div>
<div> </div>
<div>-box.internal.sql_create_function("GLOB", glob)</div>
<div> box.internal.sql_create_function("MATCH", glob)</div>
<div> box.internal.sql_create_function("REGEXP", glob)</div>
<div> local test_cases12 ={</div>
<div>@@ -1369,47 +1363,43 @@ local test_cases12 ={</div>
<div> </div>
<div> {47, "EXPR1 LIKE EXPR2"},</div>
<div> {48, "EXPR1 LIKE EXPR2 ESCAPE EXPR"},</div>
<div>- {49, "EXPR1 GLOB EXPR2"},</div>
<div>- {50, "EXPR1 GLOB EXPR2 ESCAPE EXPR"},</div>
<div>- {51, "EXPR1 REGEXP EXPR2"},</div>
<div>- {52, "EXPR1 REGEXP EXPR2 ESCAPE EXPR"},</div>
<div>- {53, "EXPR1 MATCH EXPR2"},</div>
<div>- {54, "EXPR1 MATCH EXPR2 ESCAPE EXPR"},</div>
<div>- {55, "EXPR1 NOT LIKE EXPR2"},</div>
<div>- {56, "EXPR1 NOT LIKE EXPR2 ESCAPE EXPR"},</div>
<div>- {57, "EXPR1 NOT GLOB EXPR2"},</div>
<div>- {58, "EXPR1 NOT GLOB EXPR2 ESCAPE EXPR"},</div>
<div>- {59, "EXPR1 NOT REGEXP EXPR2"},</div>
<div>- {60, "EXPR1 NOT REGEXP EXPR2 ESCAPE EXPR"},</div>
<div>- {61, "EXPR1 NOT MATCH EXPR2"},</div>
<div>- {62, "EXPR1 NOT MATCH EXPR2 ESCAPE EXPR"},</div>
<div>-</div>
<div>- {63, "EXPR IS NULL"},</div>
<div>- {64, "EXPR IS NOT NULL"},</div>
<div>-</div>
<div>- {65, "EXPR NOT BETWEEN EXPR1 AND EXPR2"},</div>
<div>- {66, "EXPR BETWEEN EXPR1 AND EXPR2"},</div>
<div>-</div>
<div>- {67, "EXPR NOT IN (SELECT cname FROM tblname)"},</div>
<div>- {68, "EXPR NOT IN (1)"},</div>
<div>- {69, "EXPR NOT IN (1, 2, 3)"},</div>
<div>- {70, "EXPR NOT IN tblname"},</div>
<div>- {71, "EXPR IN (SELECT cname FROM tblname)"},</div>
<div>- {72, "EXPR IN (1)"},</div>
<div>- {73, "EXPR IN (1, 2, 3)"},</div>
<div>- {74, "EXPR IN tblname"},</div>
<div>-</div>
<div>- {75, "EXISTS (SELECT cname FROM tblname)"},</div>
<div>- {76, "NOT EXISTS (SELECT cname FROM tblname)"},</div>
<div>-</div>
<div>- {77, "CASE EXPR WHEN EXPR1 THEN EXPR2 ELSE EXPR
END"},</div>
<div>- {78, "CASE EXPR WHEN EXPR1 THEN EXPR2 END"},</div>
<div>- {79, "CASE EXPR WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 ELSE EXPR2 END"},</div>
<div>- {80, "CASE EXPR WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 END"},</div>
<div>- {81, "CASE WHEN EXPR1 THEN EXPR2 ELSE EXPR END"},</div>
<div>- {82, "CASE WHEN EXPR1 THEN EXPR2 END"},</div>
<div>- {83, "CASE WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 ELSE EXPR2 END"},</div>
<div>- {84, "CASE WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 END"},</div>
<div>+ {49, "EXPR1 REGEXP EXPR2"},</div>
<div>+ {50, "EXPR1 REGEXP EXPR2 ESCAPE EXPR"},</div>
<div>+ {51, "EXPR1 MATCH EXPR2"},</div>
<div>+ {52, "EXPR1 MATCH EXPR2 ESCAPE EXPR"},</div>
<div>+ {53, "EXPR1 NOT LIKE EXPR2"},</div>
<div>+ {54, "EXPR1 NOT LIKE EXPR2 ESCAPE EXPR"},</div>
<div>+ {55, "EXPR1 NOT REGEXP EXPR2"},</div>
<div>+ {56, "EXPR1 NOT REGEXP EXPR2 ESCAPE EXPR"},</div>
<div>+ {57, "EXPR1 NOT MATCH EXPR2"},</div>
<div>+ {58, "EXPR1 NOT MATCH EXPR2 ESCAPE EXPR"},</div>
<div>+</div>
<div>+ {59, "EXPR IS NULL"},</div>
<div>+ {60, "EXPR IS NOT NULL"},</div>
<div>+</div>
<div>+ {61, "EXPR NOT BETWEEN EXPR1 AND EXPR2"},</div>
<div>+ {62, "EXPR BETWEEN EXPR1 AND EXPR2"},</div>
<div>+</div>
<div>+ {63, "EXPR NOT IN (SELECT cname FROM tblname)"},</div>
<div>+ {64, "EXPR NOT IN (1)"},</div>
<div>+ {65, "EXPR NOT IN (1, 2, 3)"},</div>
<div>+ {66, "EXPR NOT IN tblname"},</div>
<div>+ {67, "EXPR IN (SELECT cname FROM tblname)"},</div>
<div>+ {68, "EXPR IN (1)"},</div>
<div>+ {69, "EXPR IN (1, 2, 3)"},</div>
<div>+ {70, "EXPR IN tblname"},</div>
<div>+</div>
<div>+ {71, "EXISTS (SELECT cname FROM tblname)"},</div>
<div>+ {72, "NOT EXISTS (SELECT cname FROM tblname)"},</div>
<div>+</div>
<div>+ {73, "CASE EXPR WHEN EXPR1 THEN EXPR2 ELSE EXPR
END"},</div>
<div>+ {74, "CASE EXPR WHEN EXPR1 THEN EXPR2 END"},</div>
<div>+ {75, "CASE EXPR WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 ELSE EXPR2 END"},</div>
<div>+ {76, "CASE EXPR WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 END"},</div>
<div>+ {77, "CASE WHEN EXPR1 THEN EXPR2 ELSE EXPR END"},</div>
<div>+ {78, "CASE WHEN EXPR1 THEN EXPR2 END"},</div>
<div>+ {79, "CASE WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 ELSE EXPR2 END"},</div>
<div>+ {80, "CASE WHEN EXPR1 THEN EXPR2 WHEN EXPR THEN
EXPR1 END"},</div>
<div> }</div>
<div> </div>
<div> for _, val in ipairs(test_cases12) do</div>
<div>@@ -1802,7 +1792,7 @@ test:do_execsql_test(</div>
<div> })</div>
<div> </div>
<div> ---------------------------------------------------------------------------</div>
<div>--- Test the statements related to the LIKE and GLOB
operators.</div>
<div>+-- Test the statements related to the LIKE operator.</div>
<div> --</div>
<div> -- EVIDENCE-OF: R-16584-60189 The LIKE operator does a
pattern matching</div>
<div> -- comparison.</div>
<div>@@ -2274,102 +2264,38 @@ test:do_execsql_test(</div>
<div> -- </e_expr-16.1.7></div>
<div> })</div>
<div> </div>
<div>--- EVIDENCE-OF: R-52087-12043 The GLOB operator is
similar to LIKE but</div>
<div>--- uses the Unix file globbing syntax for its wildcards.</div>
<div>---</div>
<div>--- EVIDENCE-OF: R-09813-17279 Also, GLOB is case
sensitive, unlike LIKE.</div>
<div>+-- EVIDENCE-OF: R-39616-20555 LIKE may be preceded by
the</div>
<div>+-- NOT keyword to invert the sense of the test.</div>
<div> --</div>
<div> test:do_execsql_test(</div>
<div>- "e_expr-17.1.1",</div>
<div>- [[</div>
<div>- SELECT 'abcxyz' GLOB 'abc%'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.1.1></div>
<div>- 0</div>
<div>- -- </e_expr-17.1.1></div>
<div>- })</div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.1.2",</div>
<div>- [[</div>
<div>- SELECT 'abcxyz' GLOB 'abc*'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.1.2></div>
<div>- 1</div>
<div>- -- </e_expr-17.1.2></div>
<div>- })</div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.1.3",</div>
<div>- [[</div>
<div>- SELECT 'abcxyz' GLOB 'abc___'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.1.3></div>
<div>- 0</div>
<div>- -- </e_expr-17.1.3></div>
<div>- })</div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.1.4",</div>
<div>- [[</div>
<div>- SELECT 'abcxyz' GLOB 'abc???'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.1.4></div>
<div>- 1</div>
<div>- -- </e_expr-17.1.4></div>
<div>- })</div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.1.5",</div>
<div>+ "e_expr-17.2.0",</div>
<div> [[</div>
<div>- SELECT 'abcxyz' GLOB 'abc*'</div>
<div>+ PRAGMA case_sensitive_like = 1;</div>
<div>+ SELECT 'abcxyz' NOT LIKE 'ABC%';</div>
<div> ]], {</div>
<div>- -- <e_expr-17.1.5></div>
<div>+ -- <e_expr-17.2.0></div>
<div> 1</div>
<div>- -- </e_expr-17.1.5></div>
<div>- })</div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.1.6",</div>
<div>- [[</div>
<div>- SELECT 'ABCxyz' GLOB 'abc*'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.1.6></div>
<div>- 0</div>
<div>- -- </e_expr-17.1.6></div>
<div>- })</div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.1.7",</div>
<div>- [[</div>
<div>- SELECT 'abcxyz' GLOB 'ABC*'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.1.7></div>
<div>- 0</div>
<div>- -- </e_expr-17.1.7></div>
<div>+ -- </e_expr-17.2.0></div>
<div> })</div>
<div> </div>
<div>--- EVIDENCE-OF: R-39616-20555 Both GLOB and LIKE may be
preceded by the</div>
<div>--- NOT keyword to invert the sense of the test.</div>
<div>---</div>
<div> test:do_execsql_test(</div>
<div> "e_expr-17.2.1",</div>
<div> [[</div>
<div>- SELECT 'abcxyz' NOT GLOB 'ABC*'</div>
<div>+ SELECT 'abcxyz' NOT LIKE 'abc%'</div>
<div> ]], {</div>
<div> -- <e_expr-17.2.1></div>
<div>- 1</div>
<div>+ 0</div>
<div> -- </e_expr-17.2.1></div>
<div> })</div>
<div> </div>
<div> test:do_execsql_test(</div>
<div> "e_expr-17.2.2",</div>
<div> [[</div>
<div>- SELECT 'abcxyz' NOT GLOB 'abc*'</div>
<div>+ PRAGMA case_sensitive_like = 0</div>
<div> ]], {</div>
</div>
</div>
</blockquote>
delete 17.2.1 17.2.2 (it was creaget for glob, like tested below),
and move <br>
`PRAGMA case_sensitive_like = 0` out of the test (it is not a test)
(use just test:execsql or box.exequte)<br>
<blockquote type="cite"
cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org">
<div class="">
<div>
<div> -- <e_expr-17.2.2></div>
<div>- 0</div>
<div>- -- </e_expr-17.2.2></div>
<div>+</div>
<div>+ -- <e_expr-17.2.2></div>
<div> })</div>
<div> </div>
<div> test:do_execsql_test(</div>
<div>@@ -2448,62 +2374,6 @@ if 0>0 then</div>
<div> db("nullvalue", "")</div>
<div> end</div>
<div> </div>
<div>--- EVIDENCE-OF: R-39414-35489 The infix GLOB operator is
implemented by</div>
<div>--- calling the function glob(Y,X) and can be modified by
overriding that</div>
<div>--- function.</div>
<div>-</div>
<div>-local globargs = {}</div>
<div>-local function globfunc(...)</div>
<div>- local args = {...}</div>
<div>- for i, v in ipairs(args) do</div>
<div>- table.insert(globargs, v)</div>
<div>- end</div>
<div>- return 1</div>
<div>-end</div>
<div>-box.internal.sql_create_function("GLOB", globfunc, 2)</div>
<div>---db("func", "glob", "-argcount", 2, "globfunc")</div>
</div>
</div>
</blockquote>
Do not delete this test. Rewrite it for like.<br>
<blockquote type="cite"
cite="mid:32D1E5EA-EA21-4E4B-B5F5-80B6578BFBED@tarantool.org">
<div class="">
<div>
<div>-</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.3.1",</div>
<div>- [[</div>
<div>- SELECT 'abc' GLOB 'def'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.3.1></div>
<div>- 1</div>
<div>- -- </e_expr-17.3.1></div>
<div>- })</div>
<div>-</div>
<div>-test:do_test(</div>
<div>- "e_expr-17.3.2",</div>
<div>- function()</div>
<div>- return globargs</div>
<div>- end, {</div>
<div>- -- <e_expr-17.3.2></div>
<div>- "def", "abc"</div>
<div>- -- </e_expr-17.3.2></div>
<div>- })</div>
<div>-</div>
<div>-globargs = { }</div>
<div>-test:do_execsql_test(</div>
<div>- "e_expr-17.3.3",</div>
<div>- [[</div>
<div>- SELECT 'X' NOT GLOB 'Y'</div>
<div>- ]], {</div>
<div>- -- <e_expr-17.3.3></div>
<div>- 0</div>
<div>- -- </e_expr-17.3.3></div>
<div>- })</div>
<div>-</div>
<div>-test:do_test(</div>
<div>- "e_expr-17.3.4",</div>
<div>- function()</div>
<div>- return globargs</div>
<div>- end, {</div>
<div>- -- <e_expr-17.3.4></div>
<div>- "Y", "X"</div>
<div>- -- </e_expr-17.3.4></div>
<div>- })</div>
<div>-</div>
<div> --sqlite3("db", "test.db")</div>
<div> -- EVIDENCE-OF: R-41650-20872 No regexp() user function
is defined by</div>
<div> -- default and so use of the REGEXP operator will
normally result in an</div>
<div>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>index addf0e36d..a6d822ccd 100755</div>
<div>---
a/test/sql-tap/gh-3251-string-pattern-comparison.test.lua</div>
<div>+++
b/test/sql-tap/gh-3251-string-pattern-comparison.test.lua</div>
<div>@@ -142,17 +142,17 @@ for i, tested_string in
ipairs(invalid_testcases) do</div>
<div> local test_name = prefix .. "2." .. tostring(i)</div>
<div> local test_itself = "SELECT 'abc' LIKE 'ab" ..
tested_string .. "';"</div>
<div> test:do_catchsql_test(test_name, test_itself,</div>
<div>- {1, "LIKE or GLOB pattern can
only contain UTF-8 characters"})</div>
<div>+ {1, "LIKE pattern can only
contain UTF-8 characters"})</div>
<div> </div>
<div> test_name = prefix .. "3." .. tostring(i)</div>
<div> test_itself = "SELECT 'abc' LIKE 'abc" ..
tested_string .. "';"</div>
<div> test:do_catchsql_test(test_name, test_itself,</div>
<div>- {1, "LIKE or GLOB pattern can
only contain UTF-8 characters"})</div>
<div>+ {1, "LIKE pattern can only
contain UTF-8 characters"})</div>
<div> </div>
<div> test_name = prefix .. "4." .. tostring(i)</div>
<div> test_itself = "SELECT 'abc' LIKE 'ab" ..
tested_string .. "c';"</div>
<div> test:do_catchsql_test(test_name, test_itself,</div>
<div>- {1, "LIKE or GLOB pattern can
only contain UTF-8 characters"})</div>
<div>+ {1, "LIKE pattern can only
contain UTF-8 characters"})</div>
<div> </div>
<div> -- Just skipping if row value predicand contains
invalid character.</div>
<div> </div>
<div>@@ -185,7 +185,7 @@ local valid_testcases = {</div>
<div> </div>
<div> -- Valid testcases.</div>
<div> for i, tested_string in ipairs(valid_testcases) do</div>
<div>- test_name = prefix .. "8." .. tostring(i)</div>
<div>+ local test_name = prefix .. "8." .. tostring(i)</div>
<div> local test_itself = "SELECT 'abc' LIKE 'ab" ..
tested_string .. "';"</div>
<div> test:do_execsql_test(test_name, test_itself, {0})</div>
<div> </div>
<div>diff --git a/test/sql-tap/like2.test.lua
b/test/sql-tap/like2.test.lua</div>
<div>index abcac39fb..c6c81cb4d 100755</div>
<div>--- a/test/sql-tap/like2.test.lua</div>
<div>+++ b/test/sql-tap/like2.test.lua</div>
<div>@@ -12,11 +12,11 @@ test:plan(282)</div>
<div> -- May you find forgiveness for yourself and forgive
others.</div>
<div> -- May you share freely, never taking more than you
give.</div>
<div> --</div>
<div>--------------------------------------------------------------------------</div>
<div>--- This file implements regression tests for SQLite
library. The</div>
<div>--- focus of this file is testing the LIKE and GLOB
operators and</div>
<div>--- in particular the optimizations that occur to help
those operators</div>
<div>--- run faster.</div>
<div>+-----------------------------------------------------------------</div>
<div>+-- This file implements regression tests for SQLite
library. The</div>
<div>+-- focus of this file is testing the LIKE operator and</div>
<div>+-- in particular the optimizations that occur to help
this</div>
<div>+-- operator run faster.</div>
<div> --</div>
<div> -- $Id: like2.test,v 1.1 2008/05/26 18:33:41 drh Exp $</div>
<div> -- ["set","testdir",[["file","dirname",["argv0"]]]]</div>
</div>
</div>
</blockquote>
</body>
</html>