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

</div></blockquote></div><br class=""></div><div class="">diff:</div><div class=""><br class=""></div><div class=""><div class="">diff --git a/src/box/sql/func.c b/src/box/sql/func.c</div><div class="">index 28b435ae3..f57967bd8 100644</div><div class="">--- a/src/box/sql/func.c</div><div class="">+++ b/src/box/sql/func.c</div><div class="">@@ -631,12 +631,6 @@ static const int case_insensitive_like = 1;</div><div class="">  */</div><div class=""> static const int case_sensitive_like = 0;</div><div class=""> </div><div class="">-/**</div><div class="">- * Wildcards.</div><div class="">- */</div><div class="">-#define match_one '_'</div><div class="">-#define match_all '%'</div><div class="">-</div><div class=""> /**</div><div class="">  * Possible error returns from sql_utf8_pattern_compare().</div><div class="">  */</div><div class="">@@ -693,7 +687,7 @@ sql_utf8_pattern_compare(const char *pattern,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                </span>c = Utf8Read(pattern, pattern_end);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">         </span>if (c == SQL_INVALID_UTF8_SYMBOL)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                   </span>return SQL_INVALID_PATTERN;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">              </span>if (c == match_all) {</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">            </span>if (c == MATCH_ALL_WILDCARD) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                      </span>/**</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                 </span> * Skip over multiple "%" characters in</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                   </span> * the pattern. If there are also "_"</div><div class="">@@ -705,9 +699,10 @@ sql_utf8_pattern_compare(const char *pattern,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                 </span>       SQL_END_OF_STRING) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                          </span>if (c == SQL_INVALID_UTF8_SYMBOL)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                   </span>return SQL_INVALID_PATTERN;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                              </span>if (c != match_all && c != match_one)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                            </span>if (c != MATCH_ALL_WILDCARD &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                           </span>    c != MATCH_ONE_WILDCARD)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                      </span>break;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                           </span>if (c == match_one &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                            </span>if (c == MATCH_ONE_WILDCARD &&</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                              </span>    (c2 = Utf8Read(string, string_end)) ==</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                </span>    SQL_END_OF_STRING)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                    </span>return SQL_NOWILDCARDMATCH;</div><div class="">@@ -801,7 +796,7 @@ sql_utf8_pattern_compare(const char *pattern,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                      </span>    c == u_tolower(c2))</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                           </span>continue;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">           </span>}</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                </span>if (c == match_one && pattern != zEscaped &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">             </span>if (c == MATCH_ONE_WILDCARD && pattern != zEscaped &&</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">               </span>    c2 != SQL_END_OF_STRING)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                      </span>continue;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">           </span>return SQL_NOMATCH;</div><div class="">@@ -894,11 +889,10 @@ likeFunc(sqlite3_context *context, int argc, sqlite3_value **argv)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">               </span>const unsigned char *zEsc = sqlite3_value_text(argv[2]);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">            </span>if (zEsc == 0)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                      </span>return;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">          </span>const char *const err_msg =</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                      </span>"ESCAPE expression must be a single character";</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">           </span>if (sqlite3Utf8CharLen((char *)zEsc, -1) != 1) {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                 </span>sqlite3_result_error(context,</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                                    </span>     "ESCAPE expression must be a"</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                                   </span>     " single character",</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                                    </span>     -1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                      </span>sqlite3_result_error(context, err_msg, -1);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                 </span>return;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">             </span>}</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">           </span>escape = sqlite3Utf8Read(&zEsc);</div><div class="">@@ -911,8 +905,9 @@ likeFunc(sqlite3_context *context, int argc, sqlite3_value **argv)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>int res;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">    </span>res = sql_utf8_pattern_compare(zB, zA, *is_like_ci, escape);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>if (res == SQL_INVALID_PATTERN) {</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                </span>sqlite3_result_error(context, "LIKE pattern can only contain"</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                          </span>     " UTF-8 characters", -1);</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">               </span>const char *const err_msg =</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                      </span>"LIKE pattern can only contain UTF-8 characters";</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">              </span>sqlite3_result_error(context, err_msg, -1);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">         </span>return;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">     </span>}</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">   </span>sqlite3_result_int(context, res == SQL_MATCH);</div><div class="">diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h</div><div class="">index a805adf22..420c76bfe 100644</div><div class="">--- a/src/box/sql/sqliteInt.h</div><div class="">+++ b/src/box/sql/sqliteInt.h</div><div class="">@@ -564,6 +564,12 @@ sqlite3_snprintf(int, char *, const char *, ...);</div><div class=""> char *</div><div class=""> sqlite3_vsnprintf(int, char *, const char *, va_list);</div><div class=""> </div><div class="">+/**</div><div class="">+ * Wildcard characters used in REGEXP-like operators.</div><div class="">+ */</div><div class="">+#define MATCH_ONE_WILDCARD '_'</div><div class="">+#define MATCH_ALL_WILDCARD '%'</div><div class="">+</div><div class=""> int</div><div class=""> sql_strlike_cs(const char *zLike, const char *zStr, unsigned int cEsc);</div><div class=""> </div><div class="">diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c</div><div class="">index 2d9fb6453..616acc640 100644</div><div class="">--- a/src/box/sql/whereexpr.c</div><div class="">+++ b/src/box/sql/whereexpr.c</div><div class="">@@ -218,12 +218,6 @@ operatorMask(int op)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">  </span>return c;</div><div class=""> }</div><div class=""> </div><div class="">-/**</div><div class="">- * Wildcard characters.</div><div class="">- */</div><div class="">-#define match_one '_'</div><div class="">-#define match_all '%'</div><div class="">-</div><div class=""> #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION</div><div class=""> /**</div><div class="">  * Check to see if the given expression is a LIKE operator that</div><div class="">@@ -305,11 +299,13 @@ is_like(Parse *pParse,</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">    </span>}</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">   </span>if (z) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">            </span>cnt = 0;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">         </span>while ((c = z[cnt]) != 0 && c != match_one && c != match_all)</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">            </span>while ((c = z[cnt]) != 0 && c != MATCH_ONE_WILDCARD &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">           </span>       c != MATCH_ALL_WILDCARD)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                      </span>cnt++;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">              </span>if (cnt != 0 && 255 != (u8) z[cnt - 1]) {</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                   </span>Expr *pPrefix;</div><div class="">-<span class="Apple-tab-span" style="white-space:pre">                   </span>*pisComplete = c == match_all && z[cnt + 1] == 0;</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                        </span>*pisComplete = c == MATCH_ALL_WILDCARD &&</div><div class="">+<span class="Apple-tab-span" style="white-space:pre">                                </span>       z[cnt + 1] == 0;</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                      </span>pPrefix = sqlite3Expr(db, TK_STRING, z);</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                    </span>if (pPrefix)</div><div class=""> <span class="Apple-tab-span" style="white-space:pre">                                </span>pPrefix->u.zToken[cnt] = 0;</div><div class="">diff --git a/test/sql-tap/e_expr.test.lua b/test/sql-tap/e_expr.test.lua</div><div class="">index 0d69e8535..6d1edcfd0 100755</div><div class="">--- a/test/sql-tap/e_expr.test.lua</div><div class="">+++ b/test/sql-tap/e_expr.test.lua</div><div class="">@@ -77,7 +77,6 @@ local operations = {</div><div class="">     {"<>", "ne1"},</div><div class="">     {"!=", "ne2"},</div><div class="">     {"IS", "is"},</div><div class="">---    {"LIKE", "like"},</div><div class="">     {"AND", "and"},</div><div class="">     {"OR", "or"},</div><div class="">     {"MATCH", "match"},</div><div class="">@@ -98,7 +97,7 @@ operations = {</div><div class=""> -- Another NOTE: MATCH & REGEXP aren't supported in Tarantool &</div><div class=""> --               are waiting for their hour, don't confuse them</div><div class=""> --               being commented with commenting of "LIKE".</div><div class="">-    {"=", "==", "!=", "<>"}, --"LIKE"}, --"MATCH", "REGEXP"},</div><div class="">+    {"=", "==", "!=", "<>"}, --"MATCH", "REGEXP"},</div><div class="">     {"AND"},</div><div class="">     {"OR"},</div><div class=""> }</div><div class="">@@ -2278,10 +2277,12 @@ test:do_execsql_test(</div><div class="">         -- </e_expr-17.2.0></div><div class="">     })</div><div class=""> </div><div class="">+test:execsql("PRAGMA case_sensitive_like = 0;")</div><div class="">+</div><div class=""> test:do_execsql_test(</div><div class="">     "e_expr-17.2.1",</div><div class="">     [[</div><div class="">-        SELECT 'abcxyz' NOT LIKE 'abc%'</div><div class="">+        SELECT 'abcxyz' NOT LIKE 'ABC%'</div><div class="">     ]], {</div><div class="">         -- <e_expr-17.2.1></div><div class="">         0</div><div class="">@@ -2290,85 +2291,65 @@ test:do_execsql_test(</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class="">     "e_expr-17.2.2",</div><div class="">-    [[</div><div class="">-        PRAGMA case_sensitive_like = 0</div><div class="">-    ]], {</div><div class="">-        -- <e_expr-17.2.2></div><div class="">-</div><div class="">-        -- <e_expr-17.2.2></div><div class="">-    })</div><div class="">-</div><div class="">-test:do_execsql_test(</div><div class="">-    "e_expr-17.2.3",</div><div class="">-    [[</div><div class="">-        SELECT 'abcxyz' NOT LIKE 'ABC%'</div><div class="">-    ]], {</div><div class="">-        -- <e_expr-17.2.3></div><div class="">-        0</div><div class="">-        -- </e_expr-17.2.3></div><div class="">-    })</div><div class="">-</div><div class="">-test:do_execsql_test(</div><div class="">-    "e_expr-17.2.4",</div><div class="">     [[</div><div class="">         SELECT 'abcxyz' NOT LIKE 'abc%'</div><div class="">     ]], {</div><div class="">-        -- <e_expr-17.2.4></div><div class="">+        -- <e_expr-17.2.2></div><div class="">         0</div><div class="">-        -- </e_expr-17.2.4></div><div class="">+        -- </e_expr-17.2.2></div><div class="">     })</div><div class=""> </div><div class=""> test:do_execsql_test(</div><div class="">-    "e_expr-17.2.5",</div><div class="">+    "e_expr-17.2.3",</div><div class="">     [[</div><div class="">         SELECT 'abdxyz' NOT LIKE 'abc%'</div><div class="">     ]], {</div><div class="">-        -- <e_expr-17.2.5></div><div class="">+        -- <e_expr-17.2.3></div><div class="">         1</div><div class="">-        -- </e_expr-17.2.5></div><div class="">+        -- </e_expr-17.2.3></div><div class="">     })</div><div class=""> </div><div class=""> -- MUST_WORK_TEST uses access to nullvalue... (sql parameters) and built in functions</div><div class=""> if 0>0 then</div><div class="">     db("nullvalue", "null")</div><div class="">     test:do_execsql_test(</div><div class="">-        "e_expr-17.2.6",</div><div class="">+        "e_expr-17.2.4",</div><div class="">         [[</div><div class="">             SELECT 'abcxyz' NOT GLOB NULL</div><div class="">         ]], {</div><div class="">-            -- <e_expr-17.2.6></div><div class="">+            -- <e_expr-17.2.4></div><div class="">             "null"</div><div class="">-            -- </e_expr-17.2.6></div><div class="">+            -- </e_expr-17.2.4></div><div class="">         })</div><div class=""> </div><div class="">     test:do_execsql_test(</div><div class="">-        "e_expr-17.2.7",</div><div class="">+        "e_expr-17.2.5",</div><div class="">         [[</div><div class="">             SELECT 'abcxyz' NOT LIKE NULL</div><div class="">         ]], {</div><div class="">-            -- <e_expr-17.2.7></div><div class="">+            -- <e_expr-17.2.5></div><div class="">             "null"</div><div class="">-            -- </e_expr-17.2.7></div><div class="">+            -- </e_expr-17.2.5></div><div class="">         })</div><div class=""> </div><div class="">     test:do_execsql_test(</div><div class="">-        "e_expr-17.2.8",</div><div class="">+        "e_expr-17.2.6",</div><div class="">         [[</div><div class="">             SELECT NULL NOT GLOB 'abc*'</div><div class="">         ]], {</div><div class="">-            -- <e_expr-17.2.8></div><div class="">+            -- <e_expr-17.2.6></div><div class="">             "null"</div><div class="">-            -- </e_expr-17.2.8></div><div class="">+            -- </e_expr-17.2.6></div><div class="">         })</div><div class=""> </div><div class="">     test:do_execsql_test(</div><div class="">-        "e_expr-17.2.9",</div><div class="">+        "e_expr-17.2.7",</div><div class="">         [[</div><div class="">             SELECT NULL NOT LIKE 'ABC%'</div><div class="">         ]], {</div><div class="">-            -- <e_expr-17.2.9></div><div class="">+            -- <e_expr-17.2.7></div><div class="">             "null"</div><div class="">-            -- </e_expr-17.2.9></div><div class="">+            -- </e_expr-17.2.7></div><div class="">         })</div><div class=""> </div><div class="">     db("nullvalue", "")</div></div><div class=""><br class=""></div></body></html>