<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 01.08.2018 21:10, Nikita Tatunov
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAEi+_aqh8MSQx02PcgnSAipyoLvhgaE7Vuzv97m5k_TngcJ6Ww@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <div dir="ltr"><br>
        <br>
        <div class="gmail_quote">
          <div dir="ltr">ср, 1 авг. 2018 г. в 16:56, Alex Khatskevich
            <<a href="mailto:avkhatskevich@tarantool.org"
              moz-do-not-send="true">avkhatskevich@tarantool.org</a>>:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <p><br>
              </p>
              <br>
              <div class="gmail-m_-4474003912722141488moz-cite-prefix">On
                01.08.2018 13:51, Nikita Tatunov wrote:<br>
              </div>
              <blockquote type="cite">
                <div dir="ltr">
                  <div>diff --git a/src/box/sql/func.c
                    b/src/box/sql/func.c</div>
                  <div>index c06e3bd..7f93ef6 100644</div>
                  <div>--- a/src/box/sql/func.c</div>
                  <div>+++ b/src/box/sql/func.c</div>
                  <div>@@ -617,13 +617,17 @@ struct compareInfo {</div>
                  <div> <span style="white-space:pre-wrap">      </span>u8
                    noCase;<span style="white-space:pre-wrap">          </span>/*
                    true to ignore case differences */</div>
                  <div> };</div>
                  <div> </div>
                  <div>-/*</div>
                  <div>- * For LIKE and GLOB matching on EBCDIC
                    machines, assume that every</div>
                  <div>- * character is exactly one byte in size.  Also,
                    provde the Utf8Read()</div>
                  <div>- * macro for fast reading of the next character
                    in the common case where</div>
                  <div>- * the next character is ASCII.</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>  */</div>
                  <div>-#define Utf8Read(s, e)   
                    ucnv_getNextUChar(pUtf8conv, &s, e, &status)</div>
                  <div>+#define Utf8Read(s, e) (((s) < (e)) ? \</div>
                  <div>+<span style="white-space:pre-wrap">       </span>ucnv_getNextUChar(pUtf8conv,
                    &(s), (e), &(status)) : 0)</div>
                </div>
              </blockquote>
              [Later I will ask you to return this macro back, so, you
              may not do this]<br>
              As I understand, you are returning `0` from Utf8Read in
              case of end of the string.<br>
              Let's return `SQL_END_OF_STRING` instead of just `0`.<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Yeah, thank you, didn't notice it. <br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>+</div>
                  <div>+#define SQL_END_OF_STRING        0</div>
                  <div>+#define SQL_INVALID_UTF8_SYMBOL  0xfffd</div>
                  <div> </div>
                  <div> static const struct compareInfo globInfo = {
                    '*', '?', '[', 0 };</div>
                  <div> </div>
                  <div>@@ -638,19 +642,16 @@ static const struct
                    compareInfo likeInfoNorm = { '%', '_', 0, 1 };</div>
                  <div> static const struct compareInfo likeInfoAlt = {
                    '%', '_', 0, 0 };</div>
                  <div> </div>
                  <div> /*</div>
                  <div>- * Possible error returns from patternMatch()</div>
                  <div>+ * Possible error returns from
                    sql_utf8_pattern_compare()</div>
                  <div>  */</div>
                  <div> #define SQLITE_MATCH             0</div>
                  <div> #define SQLITE_NOMATCH           1</div>
                  <div> #define SQLITE_NOWILDCARDMATCH   2</div>
                  <div>+#define SQL_PROHIBITED_PATTERN   3</div>
                </div>
              </blockquote>
              I am not sure that the invalid (with invalid symbols)
              pattern can be called `prohibited`.<br>
              Rename somehow? My proposal: SQL_INVALID_PATTERN.<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Probably you're right, I was also thinking of changing it
            somehow.</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF"> Moreover, You have named this
              definition with the `SQL` prefix, which is good, however,<br>
              similar definitions are still prefixed with `SQLITE`. I
              would like you to rename those in<br>
              this (preferred) or in a separate commit for consistency.
              <blockquote type="cite">
                <div dir="ltr">
                  <div> </div>
                </div>
              </blockquote>
            </div>
          </blockquote>
          <div>Tarantool != SQLite and I think we should get away from
            this approach.</div>
          <div>The thing that names haven't been refactored yet isn't in
            my control.</div>
          <div>You can ask Nikita's opinion on it, I guess he will tell
            you almost the same.</div>
        </div>
      </div>
    </blockquote>
    I have consult @nikita and he asked to rename those SQLITE to SQL.<br>
    <blockquote type="cite"
cite="mid:CAEi+_aqh8MSQx02PcgnSAipyoLvhgaE7Vuzv97m5k_TngcJ6Ww@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>-/*</div>
                  <div>- * Compare two UTF-8 strings for equality where
                    the first string is</div>
                  <div>- * a GLOB or LIKE expression.  Return values:</div>
                  <div>- *</div>
                  <div>- *    SQLITE_MATCH:            Match</div>
                  <div>- *    SQLITE_NOMATCH:          No match</div>
                  <div>- *    SQLITE_NOWILDCARDMATCH:  No match in spite
                    of having * or % wildcards.</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>@@ -663,92 +664,136 @@ static const struct
                    compareInfo likeInfoAlt = { '%', '_', 0, 0 };</div>
                  <div>  *</div>
                  <div>  *     [^...]     Matches one character not in
                    the enclosed list.</div>
                  <div>  *</div>
                  <div>- * With the [...] and [^...] matching, a ']'
                    character can be included</div>
                  <div>- * in the list by making it the first character
                    after '[' or '^'.  A</div>
                  <div>- * range of characters can be specified using
                    '-'.  Example:</div>
                  <div>- * "[a-z]" matches any single lower-case
                    letter.  To match a '-', make</div>
                  <div>- * it the last character in the list.</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>
              </blockquote>
              Does it work for UTF characters? I suppose no.<br>
              Let's write about it here + let's file an issue to make it<br>
              work with UTF characters.</div>
          </blockquote>
          <div><br>
          </div>
          <div>Soon this function is gonna be refactored & GLOB is
            gonna be removed anyways.</div>
        </div>
      </div>
    </blockquote>
    Yes. you will find comment on it below.<br>
    <blockquote type="cite"
cite="mid:CAEi+_aqh8MSQx02PcgnSAipyoLvhgaE7Vuzv97m5k_TngcJ6Ww@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <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 characters.</div>
                  <div>  *</div>
                  <div>- **     '_'       Matches any one character</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 exactly c.</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>  *</div>
                  <div>- * This routine is usually quick, but can be
                    N**2 in the worst case.</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>+ *</div>
                  <div>+ * @retval SQLITE_MATCH:            Match.</div>
                  <div>+ *<span style="white-space:pre-wrap">     </span> 
                     SQLITE_NOMATCH:          No match.</div>
                  <div>+ *<span style="white-space:pre-wrap">     </span> 
                     SQLITE_NOWILDCARDMATCH:  No match in spite of
                    having *</div>
                  <div>+ *<span style="white-space:pre-wrap">                             </span> 
                      or % wildcards.</div>
                  <div>+ *<span style="white-space:pre-wrap">     </span> 
                     SQL_PROHIBITED_PATTERN:  Pattern contains invalid</div>
                  <div>+ *<span style="white-space:pre-wrap">                             </span> 
                      symbol.</div>
                </div>
              </blockquote>
              Minor: It is not very good that you use symbol and
              character interchangeably.<br>
              I suppose that `character` should be used everywhere.</div>
          </blockquote>
          <div><br>
          </div>
          <div>They're synonyms, aren't they? </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>  */</div>
                  <div> static int</div>
                  <div>-patternCompare(const char * pattern,<span style="white-space:pre-wrap">   </span>/*
                    The glob pattern */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>     
                     const char * string,<span style="white-space:pre-wrap">   </span>/*
                    The string to compare against the glob */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>     
                     const struct compareInfo *pInfo,<span style="white-space:pre-wrap">       </span>/*
                    Information about how to do the compare */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>     
                     UChar32 matchOther<span style="white-space:pre-wrap">     </span>/*
                    The escape char (LIKE) or '[' (GLOB) */</div>
                  <div>-    )</div>
                  <div>+sql_utf8_pattern_compare(const char * pattern,</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>
                    const char * string,</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>
                    const struct compareInfo *pInfo,</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>
                    UChar32 matchOther)</div>
                </div>
              </blockquote>
              "star" sign should stick to the attribute  name.<br>
              <a
                class="gmail-m_-4474003912722141488moz-txt-link-freetext"
href="https://tarantool.io/en/doc/1.9/dev_guide/c_style_guide/#chapter-3-1-spaces"
                target="_blank" moz-do-not-send="true">https://tarantool.io/en/doc/1.9/dev_guide/c_style_guide/#chapter-3-1-spaces</a><br>
              <br>
              To prevent such typos in the future, you can use special
              perl<br>
              script which checks coding style in Linux kernel patches.</div>
          </blockquote>
          <div><br>
          </div>
          <div>Subject of the ticket wasn't about refactoring function,
            but thnx, changed it.</div>
          <div>REMEMBER THIS POINT #1 </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div> {</div>
                  <div>-<span style="white-space:pre-wrap">       </span>UChar32
                    c, c2;<span style="white-space:pre-wrap">           </span>/*
                    Next pattern and input string chars */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>UChar32
                    matchOne = pInfo->matchOne;<span style="white-space:pre-wrap">   </span>/*
                    "?" or "_" */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>UChar32
                    matchAll = pInfo->matchAll;<span style="white-space:pre-wrap">   </span>/*
                    "*" or "%" */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>UChar32
                    noCase = pInfo->noCase;<span style="white-space:pre-wrap">       </span>/*
                    True if uppercase==lowercase */</div>
                  <div>-<span style="white-space:pre-wrap">       </span>const
                    char *zEscaped = 0;<span style="white-space:pre-wrap">      </span>/*
                    One past the last escaped input char */</div>
                  <div>+<span style="white-space:pre-wrap">       </span>/*
                    Next pattern and input string chars */</div>
                  <div>+<span style="white-space:pre-wrap">       </span>UChar32
                    c, c2;</div>
                  <div>+<span style="white-space:pre-wrap">       </span>/*
                    "?" or "_" */</div>
                  <div>+<span style="white-space:pre-wrap">       </span>UChar32
                    matchOne = pInfo->matchOne;</div>
                  <div>+<span style="white-space:pre-wrap">       </span>/*
                    "*" or "%" */</div>
                  <div>+<span style="white-space:pre-wrap">       </span>UChar32
                    matchAll = pInfo->matchAll;</div>
                  <div>+<span style="white-space:pre-wrap">       </span>/*
                    True if uppercase==lowercase */</div>
                  <div>+<span style="white-space:pre-wrap">       </span>UChar32
                    noCase = pInfo->noCase;</div>
                  <div>+<span style="white-space:pre-wrap">       </span>/*
                    One past the last escaped input char */</div>
                  <div>+<span style="white-space:pre-wrap">       </span>const
                    char *zEscaped = 0;</div>
                  <div> <span style="white-space:pre-wrap">      </span>const
                    char * pattern_end = pattern + strlen(pattern);</div>
                  <div> <span style="white-space:pre-wrap">      </span>const
                    char * string_end = string + strlen(string);</div>
                  <div> <span style="white-space:pre-wrap">      </span>UErrorCode
                    status = U_ZERO_ERROR;</div>
                  <div> </div>
                  <div>-<span style="white-space:pre-wrap">       </span>while
                    (pattern < pattern_end){</div>
                  <div>-<span style="white-space:pre-wrap">               </span>c =
                    Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">       </span>while
                    ((c = Utf8Read(pattern, pattern_end)) !=
                    SQL_END_OF_STRING) {</div>
                </div>
              </blockquote>
              REMEMBER THIS POINT #1<br>
              <blockquote type="cite">
                <div dir="ltr">
                  <div>+<span style="white-space:pre-wrap">               </span>if
                    (c == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">              </span>if
                    (c == matchAll) {<span style="white-space:pre-wrap">        </span>/*
                    Match "*" */</div>
                  <div>-<span style="white-space:pre-wrap">                       </span>/*
                    Skip over multiple "*" characters in the pattern. 
                    If there</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    are also "?" characters, skip those as well, but
                    consume a</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    single character of the input string for each "?"
                    skipped</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>/*
                    Skip over multiple "*" characters in</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    the pattern. If there are also "?"</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    characters, skip those as well, but</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    consume a single character of the</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    input string for each "?" skipped.</div>
                  <div> <span style="white-space:pre-wrap">                      </span> */</div>
                  <div>-<span style="white-space:pre-wrap">                       </span>while
                    (pattern < pattern_end){</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>c
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>while
                    ((c = Utf8Read(pattern, pattern_end)) !=</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>   
                       SQL_END_OF_STRING) {</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (c != matchAll && c != matchOne)</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>break;</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>if
                    (c == matchOne</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> 
                      && Utf8Read(string, string_end) == 0) {</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c == matchOne &&</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> 
                      (c2 = Utf8Read(string, string_end)) ==</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> 
                      SQL_END_OF_STRING)</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>return
                    SQLITE_NOWILDCARDMATCH;</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>}</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                      </span>}</div>
                  <div>-<span style="white-space:pre-wrap">                       </span>/*
                    "*" at the end of the pattern matches */</div>
                  <div>-<span style="white-space:pre-wrap">                       </span>if
                    (pattern == pattern_end)</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>/*</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    "*" at the end of the pattern matches.</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> */</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>if
                    (c == SQL_END_OF_STRING) {</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>while
                    ((c2 = Utf8Read(string, string_end)) !=</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> 
                         SQL_END_OF_STRING)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>return
                    SQLITE_MATCH;</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>}</div>
                  <div> <span style="white-space:pre-wrap">                      </span>if
                    (c == matchOther) {</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (pInfo->matchSet == 0) {</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>c
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>-<span style="white-space:pre-wrap">                                       </span>if
                    (c == 0)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>if
                    (c == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>if
                    (c == SQL_END_OF_STRING)</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>return
                    SQLITE_NOWILDCARDMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}
                    else {</div>
                  <div>-<span style="white-space:pre-wrap">                                       </span>/*
                    "[...]" immediately follows the "*".  We have to do
                    a slow</div>
                  <div>-<span style="white-space:pre-wrap">                                       </span>
                    * recursive search in this case, but it is an
                    unusual case.</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>/*
                    "[...]" immediately</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>
                    * follows the "*". We</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>
                    * have to do a slow</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>
                    * recursive search in</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>
                    * this case, but it is</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>
                    * an unusual case.</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>
                    */</div>
                  <div>-<span style="white-space:pre-wrap">                                       </span>assert(matchOther
                    < 0x80);<span style="white-space:pre-wrap">      </span>/*
                    '[' is a single-byte character */</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>assert(matchOther
                    < 0x80);</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>while
                    (string < string_end) {</div>
                </div>
              </blockquote>
              REMEMBER THIS POINT #2<br>
              <br>
              <blockquote type="cite">
                <div dir="ltr">
                  <div> <span style="white-space:pre-wrap">                                              </span>int
                    bMatch =</div>
                  <div>-<span style="white-space:pre-wrap">                                               </span> 
                      patternCompare(&pattern[-1],</div>
                  <div>-<span style="white-space:pre-wrap">                                                               </span> 
                     string,</div>
                  <div>-<span style="white-space:pre-wrap">                                                               </span> 
                     pInfo,</div>
                  <div>-<span style="white-space:pre-wrap">                                                               </span> 
                     matchOther);</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span> 
                      sql_utf8_pattern_compare(</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span>&pattern[-1],</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span>string,</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span>pInfo,</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span>matchOther);</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>if
                    (bMatch != SQLITE_NOMATCH)</div>
                  <div> <span style="white-space:pre-wrap">                                                      </span>return
                    bMatch;</div>
                  <div>-<span style="white-space:pre-wrap">                                               </span>Utf8Read(string,
                    string_end);</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>c
                    = Utf8Read(string, string_end);</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>if
                    (c == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                                       </span>return
                    SQLITE_NOMATCH;</div>
                </div>
              </blockquote>
              look at <REMEMBER THIS POINT #1,2> and other
              `Utf8Read` usages.<br>
              You have introduced SQL_END_OF_STRING and changed
              `Utf8Read` pattern to use it in<br>
              half of cases?<br>
              <br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div><span
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">1)
              Look at <REMEMBER THIS POINT #1>.</span><br>
          </div>
          <div><span
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span
style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">2)
                I have introduced it not to use explicit 0 and to fix
                the bug.</span></span></div>
          <div><span
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">3)
              Fixed it though.</span></div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF"> Moreover,in that place you do check
              `string < string_end` implicitly inside of<br>
              `Utf8Read` but you never use that result. <br>
            </div>
          </blockquote>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF"> I suppose you should return old
              iteration style and `Utf8Read` macro.<br>
              ```<br>
              while (string < string_end) {<br>
              <span style="white-space:pre-wrap"></span>    c =
              Utf8Read(string, string_end);
              <div><span style="white-space:pre-wrap">    </span>if (c
                == SQL_INVALID_UTF8_SYMBOL)<br>
                       <span style="white-space:pre-wrap"> </span>return
                SQLITE_NOMATCH;</div>
              ```<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>I think it's better to use this approach, but yes: return
            prev. version of macro:</div>
          <div>1) 'zero byte' ticket will be partially fixed.</div>
          <div>2) 0xffff<span
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>is</span> non-unicode<span
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>anyways</span>.</div>
        </div>
      </div>
    </blockquote>
    As we concluded verbally, please, return the old style iteration.
    (`while (string < string_end)`)
    <blockquote type="cite"
cite="mid:CAEi+_aqh8MSQx02PcgnSAipyoLvhgaE7Vuzv97m5k_TngcJ6Ww@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div> <span style="white-space:pre-wrap">                                      </span>}</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>return
                    SQLITE_NOWILDCARDMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}</div>
                  <div> <span style="white-space:pre-wrap">                      </span>}</div>
                  <div> </div>
                  <div>-<span style="white-space:pre-wrap">                       </span>/*
                    At this point variable c contains the first
                    character of the</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    pattern string past the "*".  Search in the input
                    string for the</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    first matching character and recursively continue
                    the match from</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    that point.</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>/*
                    At this point variable c contains the</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    first character of the pattern string</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    past the "*". Search in the input</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    string for the first matching</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    character and recursively continue the</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    match from that point.</div>
                  <div> <span style="white-space:pre-wrap">                      </span> *</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    For a case-insensitive search, set variable cx to be
                    the same as</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    c but in the other case and search the input string
                    for either</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    c or cx.</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    For a case-insensitive search, set</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    variable cx to be the same as c but in</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    the other case and search the input</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    string for either c or cx.</div>
                  <div> <span style="white-space:pre-wrap">                      </span> */</div>
                  <div> </div>
                  <div> <span style="white-space:pre-wrap">                      </span>int
                    bMatch;</div>
                  <div>@@ -756,14 +801,18 @@ patternCompare(const char *
                    pattern,<span style="white-space:pre-wrap"> </span>/*
                    The glob pattern */</div>
                  <div> <span style="white-space:pre-wrap">                              </span>c
                    = u_tolower(c);</div>
                  <div> <span style="white-space:pre-wrap">                      </span>while
                    (string < string_end){</div>
                  <div> <span style="white-space:pre-wrap">                              </span>/**</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> *
                    This loop could have been implemented</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> *
                    without if converting c2 to lower case</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> *
                    (by holding c_upper and c_lower), however</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> *
                    it is implemented this way because lower</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> *
                    works better with German and Turkish</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> *
                    languages.</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    This loop could have been</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    implemented without if</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    converting c2 to lower case</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    by holding c_upper and</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    c_lower,however it is</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    implemented this way because</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    lower works better with German</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> *
                    and Turkish languages.</div>
                  <div> <span style="white-space:pre-wrap">                              </span>
                    */</div>
                  <div> <span style="white-space:pre-wrap">                              </span>c2
                    = Utf8Read(string, string_end);</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (!noCase) {</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>if
                    (c2 != c)</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>continue;</div>
                  <div>@@ -771,9 +820,10 @@ patternCompare(const char *
                    pattern,<span style="white-space:pre-wrap"> </span>/*
                    The glob pattern */</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>if
                    (c2 != c && u_tolower(c2) != c)</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>continue;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>bMatch
                    =</div>
                  <div>-<span style="white-space:pre-wrap">                               </span> 
                      patternCompare(pattern, string,</div>
                  <div>-<span style="white-space:pre-wrap">                                               </span> 
                     pInfo, matchOther);</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>bMatch
                    = sql_utf8_pattern_compare(pattern,</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span> 
                    string,</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span> 
                    pInfo,</div>
                  <div>+<span style="white-space:pre-wrap">                                                               </span> 
                    matchOther);</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (bMatch != SQLITE_NOMATCH)</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>return
                    bMatch;</div>
                  <div> <span style="white-space:pre-wrap">                      </span>}</div>
                  <div>@@ -782,7 +832,9 @@ patternCompare(const char *
                    pattern,<span style="white-space:pre-wrap"> </span>/*
                    The glob pattern */</div>
                  <div> <span style="white-space:pre-wrap">              </span>if
                    (c == matchOther) {</div>
                  <div> <span style="white-space:pre-wrap">                      </span>if
                    (pInfo->matchSet == 0) {</div>
                  <div> <span style="white-space:pre-wrap">                              </span>c
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>if
                    (c == 0)</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c == SQL_END_OF_STRING)</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>zEscaped
                    = pattern;</div>
                  <div> <span style="white-space:pre-wrap">                      </span>}
                    else {</div>
                  <div>@@ -790,23 +842,33 @@ patternCompare(const char *
                    pattern,<span style="white-space:pre-wrap"> </span>/*
                    The glob pattern */</div>
                  <div> <span style="white-space:pre-wrap">                              </span>int
                    seen = 0;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>int
                    invert = 0;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>c
                    = Utf8Read(string, string_end);</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (string == string_end)</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>c2
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (c2 == '^') {</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>invert
                    = 1;</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>c2
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}</div>
                  <div> <span style="white-space:pre-wrap">                              </span>if
                    (c2 == ']') {</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>if
                    (c == ']')</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>seen
                    = 1;</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>c2
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>while
                    (c2 && c2 != ']') {</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>while
                    (c2 != SQL_END_OF_STRING && c2 != ']') {</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>if
                    (c2 == '-' && pattern[0] != ']'</div>
                  <div> <span style="white-space:pre-wrap">                                      </span> 
                      && pattern < pattern_end</div>
                  <div> <span style="white-space:pre-wrap">                                      </span> 
                      && prior_c > 0) {</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>c2
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                                       </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>if
                    (c >= prior_c && c <= c2)</div>
                  <div> <span style="white-space:pre-wrap">                                                      </span>seen
                    = 1;</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>prior_c
                    = 0;</div>
                  <div>@@ -817,29 +879,36 @@ patternCompare(const char *
                    pattern,<span style="white-space:pre-wrap"> </span>/*
                    The glob pattern */</div>
                  <div> <span style="white-space:pre-wrap">                                              </span>prior_c
                    = c2;</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>}</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>c2
                    = Utf8Read(pattern, pattern_end);</div>
                  <div>+<span style="white-space:pre-wrap">                                       </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                                               </span>return
                    SQL_PROHIBITED_PATTERN;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}</div>
                  <div>-<span style="white-space:pre-wrap">                               </span>if
                    (pattern == pattern_end || (seen ^ invert) == 0) {</div>
                  <div>+<span style="white-space:pre-wrap">                               </span>if
                    (pattern == pattern_end ||</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> 
                      (seen ^ invert) == 0) {</div>
                  <div> <span style="white-space:pre-wrap">                                      </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">                              </span>}</div>
                  <div> <span style="white-space:pre-wrap">                              </span>continue;</div>
                  <div> <span style="white-space:pre-wrap">                      </span>}</div>
                  <div> <span style="white-space:pre-wrap">              </span>}</div>
                  <div> <span style="white-space:pre-wrap">              </span>c2 =
                    Utf8Read(string, string_end);</div>
                  <div>+<span style="white-space:pre-wrap">               </span>if
                    (c2 == SQL_INVALID_UTF8_SYMBOL)</div>
                  <div>+<span style="white-space:pre-wrap">                       </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">              </span>if
                    (c == c2)</div>
                  <div> <span style="white-space:pre-wrap">                      </span>continue;</div>
                  <div> <span style="white-space:pre-wrap">              </span>if
                    (noCase){</div>
                  <div> <span style="white-space:pre-wrap">                      </span>/**</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    Small optimisation. Reduce number of calls</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    to u_tolower function.</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    SQL standards suggest use to_upper for symbol</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    normalisation. However, using to_lower allows to</div>
                  <div>-<span style="white-space:pre-wrap">                       </span> *
                    respect Turkish 'İ' in default locale.</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    Small optimisation. Reduce number of</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    calls to u_tolower function. SQL</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    standards suggest use to_upper for</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    symbol normalisation. However, using</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    to_lower allows to respect Turkish 'İ'</div>
                  <div>+<span style="white-space:pre-wrap">                       </span> *
                    in default locale.</div>
                  <div> <span style="white-space:pre-wrap">                      </span> */</div>
                  <div> <span style="white-space:pre-wrap">                      </span>if
                    (u_tolower(c) == c2 ||</div>
                  <div> <span style="white-space:pre-wrap">                      </span>   
                    c == u_tolower(c2))</div>
                  <div> <span style="white-space:pre-wrap">                              </span>continue;</div>
                  <div> <span style="white-space:pre-wrap">              </span>}</div>
                  <div>-<span style="white-space:pre-wrap">               </span>if
                    (c == matchOne && pattern != zEscaped
                    && c2 != 0)</div>
                  <div>+<span style="white-space:pre-wrap">               </span>if
                    (c == matchOne && pattern != zEscaped
                    &&</div>
                  <div>+<span style="white-space:pre-wrap">               </span>   
                    c2 != SQL_END_OF_STRING)</div>
                  <div> <span style="white-space:pre-wrap">                      </span>continue;</div>
                  <div> <span style="white-space:pre-wrap">              </span>return
                    SQLITE_NOMATCH;</div>
                  <div> <span style="white-space:pre-wrap">      </span>}</div>
                  <div>@@ -853,8 +922,7 @@ patternCompare(const char *
                    pattern,<span style="white-space:pre-wrap"> </span>/*
                    The glob pattern */</div>
                  <div> int</div>
                  <div> sqlite3_strglob(const char *zGlobPattern, const
                    char *zString)</div>
                  <div> {</div>
                  <div>-<span style="white-space:pre-wrap">       </span>return
                    patternCompare(zGlobPattern, zString, &globInfo,</div>
                  <div>-<span style="white-space:pre-wrap">                       </span>   
                      '[');</div>
                  <div>+<span style="white-space:pre-wrap">       </span>return
                    sql_utf8_pattern_compare(zGlobPattern, zString,
                    &globInfo, '[');</div>
                  <div> }</div>
                  <div> </div>
                  <div> /*</div>
                  <div>@@ -864,7 +932,7 @@ sqlite3_strglob(const char
                    *zGlobPattern, const char *zString)</div>
                  <div> int</div>
                  <div> sqlite3_strlike(const char *zPattern, const char
                    *zStr, unsigned int esc)</div>
                  <div> {</div>
                  <div>-<span style="white-space:pre-wrap">       </span>return
                    patternCompare(zPattern, zStr, &likeInfoNorm,
                    esc);</div>
                  <div>+<span style="white-space:pre-wrap">       </span>return
                    sql_utf8_pattern_compare(zPattern, zStr,
                    &likeInfoNorm, esc);</div>
                  <div> }</div>
                  <div> </div>
                  <div> /*</div>
                  <div>@@ -910,8 +978,9 @@ likeFunc(sqlite3_context *
                    context, int argc, sqlite3_value ** argv)</div>
                  <div> <span style="white-space:pre-wrap">      </span>zB =
                    (const char *) sqlite3_value_text(argv[0]);</div>
                  <div> <span style="white-space:pre-wrap">      </span>zA =
                    (const char *) sqlite3_value_text(argv[1]);</div>
                  <div> </div>
                  <div>-<span style="white-space:pre-wrap">       </span>/*
                    Limit the length of the LIKE or GLOB pattern to
                    avoid problems</div>
                  <div>-<span style="white-space:pre-wrap">       </span> * of
                    deep recursion and N*N behavior in patternCompare().</div>
                  <div>+<span style="white-space:pre-wrap">       </span>/*
                    Limit the length of the LIKE or GLOB pattern to
                    avoid</div>
                  <div>+<span style="white-space:pre-wrap">       </span> *
                    problems of deep recursion and N*N behavior in</div>
                  <div>+<span style="white-space:pre-wrap">       </span> *
                    sql_utf8_pattern_compare().</div>
                  <div> <span style="white-space:pre-wrap">      </span> */</div>
                  <div> <span style="white-space:pre-wrap">      </span>nPat
                    = sqlite3_value_bytes(argv[0]);</div>
                  <div> <span style="white-space:pre-wrap">      </span>testcase(nPat
                    == db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]);</div>
                  <div>@@ -947,7 +1016,12 @@ likeFunc(sqlite3_context *
                    context, int argc, sqlite3_value ** argv)</div>
                  <div> <span style="white-space:pre-wrap">      </span>sqlite3_like_count++;</div>
                  <div> #endif</div>
                  <div> <span style="white-space:pre-wrap">      </span>int
                    res;</div>
                  <div>-<span style="white-space:pre-wrap">       </span>res =
                    patternCompare(zB, zA, pInfo, escape);</div>
                  <div>+<span style="white-space:pre-wrap">       </span>res =
                    sql_utf8_pattern_compare(zB, zA, pInfo, escape);</div>
                  <div>+<span style="white-space:pre-wrap">       </span>if
                    (res == SQL_PROHIBITED_PATTERN) {</div>
                  <div>+<span style="white-space:pre-wrap">               </span>sqlite3_result_error(context,
                    "LIKE or GLOB pattern can only"</div>
                  <div>+<span style="white-space:pre-wrap">                               </span> 
                       " contain UTF-8 characters", -1);</div>
                  <div>+<span style="white-space:pre-wrap">               </span>return;</div>
                  <div>+<span style="white-space:pre-wrap">       </span>}</div>
                  <div> <span style="white-space:pre-wrap">      </span>sqlite3_result_int(context,
                    res == SQLITE_MATCH);</div>
                  <div> }</div>
                  <div> </div>
                  <div>diff --git a/test-run b/test-run</div>
                  <div>index 77e9327..95562e9 160000</div>
                  <div>--- a/test-run</div>
                  <div>+++ b/test-run</div>
                  <div>@@ -1 +1 @@</div>
                  <div>-Subproject commit
                    77e93279210f8c5c1fd0ed03416fa19a184f0b6d</div>
                  <div>+Subproject commit
                    95562e95401fef4e0b755ab0bb430974b5d1a29a</div>
                  <div>diff --git a/test/sql-tap/e_expr.test.lua
                    b/test/sql-tap/e_expr.test.lua</div>
                  <div>index 13d3a96..9780d2c 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(12431)</div>
                  <div>+test:plan(10665)</div>
                  <div> </div>
                  <div> --!./tcltestrunner.lua</div>
                  <div> -- 2010 July 16</div>
                  <div>@@ -77,8 +77,10 @@ local operations = {</div>
                  <div>     {"<>", "ne1"},</div>
                  <div>     {"!=", "ne2"},</div>
                  <div>     {"IS", "is"},</div>
                  <div>-    {"LIKE", "like"},</div>
                  <div>-    {"GLOB", "glob"},</div>
                  <div>+-- NOTE: This test needs refactoring after
                    deletion of GLOB &</div>
                  <div>+--<span style="white-space:pre-wrap">     </span>
                    type restrictions for LIKE. (See #3572)</div>
                  <div>+--    {"LIKE", "like"},</div>
                  <div>+--    {"GLOB", "glob"},</div>
                </div>
              </blockquote>
              Yes, this behavior is not valid anymore.<br>
              To make sure that likes and globs will be tested in the
              future, please, delete this<br>
              commented lines and add your own simple test, which tries
              to call `like` and `glob`<br>
              with inappropriate types.<br>
              It is important to have a functional tests for any
              possible behavior.<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>1) Globs are going to be deleted as you can see few lines
            above.</div>
        </div>
      </div>
    </blockquote>
    I had a talk with @kirill, we decided to not maintain those tests
    and to not leave<br>
    glob w/o tests. So, please, delete glob in a different commit and
    place this commit on top of it.<br>
    <blockquote type="cite"
cite="mid:CAEi+_aqh8MSQx02PcgnSAipyoLvhgaE7Vuzv97m5k_TngcJ6Ww@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div>2) I'm gonna refactor that when LIKE is in its final
            state (basically after #3572 is closed</div>
          <div>& static build is into 2.1).</div>
        </div>
      </div>
    </blockquote>
    There are 2 options:<br>
    1. You implement those tests now and we are pushing this commit<br>
    2. You rebase this branch on static types and add those tests and we
    push this commit after static types.<br>
    Those tests = test behavior of like with different types passed.<br>
    <blockquote type="cite"
cite="mid:CAEi+_aqh8MSQx02PcgnSAipyoLvhgaE7Vuzv97m5k_TngcJ6Ww@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>     {"AND", "and"},</div>
                  <div>     {"OR", "or"},</div>
                  <div>     {"MATCH", "match"},</div>
                  <div>@@ -96,7 +98,12 @@ operations = {</div>
                  <div>     {"+", "-"},</div>
                  <div>     {"<<", ">>", "&", "|"},</div>
                  <div>     {"<", "<=", ">", ">="},</div>
                  <div>-    {"=", "==", "!=", "<>", "LIKE",
                    "GLOB"}, --"MATCH", "REGEXP"},</div>
                  <div>+-- NOTE: This test needs refactoring after
                    deletion of GLOB &</div>
                  <div>+--<span style="white-space:pre-wrap">     </span>
                    type restrictions for LIKE. (See #3572)</div>
                  <div>+-- Another NOTE: MATCH & REGEXP aren't
                    supported in Tarantool &</div>
                  <div>+-- <span style="white-space:pre-wrap">            </span>
                    are waiting for their hour, don't confuse them</div>
                  <div>+--<span style="white-space:pre-wrap">             </span>
                    being commented with ticket above.</div>
                  <div>+    {"=", "==", "!=", "<>"}, --"LIKE",
                    "GLOB"}, --"MATCH", "REGEXP"},</div>
                  <div>     {"AND"},</div>
                  <div>     {"OR"},</div>
                  <div> }</div>
                  <div>@@ -475,6 +482,7 @@ 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>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>new file mode 100755</div>
                  <div>index 0000000..2a787f2</div>
                  <div>--- /dev/null</div>
                  <div>+++
                    b/test/sql-tap/gh-3251-string-pattern-comparison.test.lua</div>
                  <div>@@ -0,0 +1,213 @@</div>
                  <div>+#!/usr/bin/env tarantool</div>
                  <div>+test = require("sqltester")</div>
                  <div>+test:plan(128)</div>
                  <div>+</div>
                  <div>+local prefix = "like-test-"</div>
                  <div>+</div>
                  <div>+-- Unicode byte sequences.</div>
                  <div>+local valid_testcases = {</div>
                  <div>+    '\x01',</div>
                  <div>+    '\x09',</div>
                  <div>+    '\x1F',</div>
                  <div>+    '\x7F',</div>
                  <div>+    '\xC2\x80',</div>
                  <div>+    '\xC2\x90',</div>
                  <div>+    '\xC2\x9F',</div>
                  <div>+    '\xE2\x80\xA8',</div>
                  <div>+    '\x20\x0B',</div>
                  <div>+    '\xE2\x80\xA9',</div>
                  <div>+}</div>
                </div>
              </blockquote>
              optional: add descriptions to those byte sequences (what
              it is).<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Some valid unicode symbols which is only that matters for
            LIKE operator.</div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>+</div>
                  <div>+-- Non-Unicode byte sequences.</div>
                  <div>+local invalid_testcases = {</div>
                  <div>+    '\xE2\x80',</div>
                  <div>+    '\xFE\xFF',</div>
                  <div>+    '\xC2',</div>
                  <div>+    '\xED\xB0\x80',</div>
                  <div>+    '\xD0',</div>
                  <div>+}</div>
                </div>
              </blockquote>
              Place that after like_test_cases, just before it is used.<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Changed it.</div>
          <div> <br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>+</div>
                  <div>+local like_test_cases =</div>
                  <div>+{</div>
                  <div>+    {"1.1",</div>
                  <div>+        "SELECT 'AB' LIKE '_B';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.2",</div>
                  <div>+        "SELECT 'CD' LIKE '_B';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.3",</div>
                  <div>+        "SELECT '' LIKE '_B';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.4",</div>
                  <div>+        "SELECT 'AB' LIKE '%B';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.5",</div>
                  <div>+        "SELECT 'CD' LIKE '%B';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.6",</div>
                  <div>+        "SELECT '' LIKE '%B';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.7",</div>
                  <div>+        "SELECT 'AB' LIKE 'A__';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.8",</div>
                  <div>+        "SELECT 'CD' LIKE 'A__';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.9",</div>
                  <div>+        "SELECT '' LIKE 'A__';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.10",</div>
                  <div>+        "SELECT 'AB' LIKE 'A_';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.11",</div>
                  <div>+        "SELECT 'CD' LIKE 'A_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.12",</div>
                  <div>+        "SELECT '' LIKE 'A_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.13",</div>
                  <div>+        "SELECT 'AB' LIKE 'A';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.14",</div>
                  <div>+        "SELECT 'CD' LIKE 'A';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.15",</div>
                  <div>+        "SELECT '' LIKE 'A';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.16",</div>
                  <div>+        "SELECT 'AB' LIKE '_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.17",</div>
                  <div>+        "SELECT 'CD' LIKE '_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.18",</div>
                  <div>+        "SELECT '' LIKE '_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.19",</div>
                  <div>+        "SELECT 'AB' LIKE '__';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.20",</div>
                  <div>+        "SELECT 'CD' LIKE '__';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.21",</div>
                  <div>+        "SELECT '' LIKE '__';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.22",</div>
                  <div>+        "SELECT 'AB' LIKE '%A';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.23",</div>
                  <div>+        "SELECT 'AB' LIKE '%C';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.24",</div>
                  <div>+        "SELECT 'ab' LIKE '%df';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.25",</div>
                  <div>+        "SELECT 'abCDF' LIKE '%df';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.26",</div>
                  <div>+        "SELECT 'CDF' LIKE '%df';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.27",</div>
                  <div>+        "SELECT 'ab' LIKE 'a_';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.28",</div>
                  <div>+        "SELECT 'abCDF' LIKE 'a_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.29",</div>
                  <div>+        "SELECT 'CDF' LIKE 'a_';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.30",</div>
                  <div>+        "SELECT 'ab' LIKE 'ab%';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.31",</div>
                  <div>+        "SELECT 'abCDF' LIKE 'ab%';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.32",</div>
                  <div>+        "SELECT 'CDF' LIKE 'ab%';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.33",</div>
                  <div>+        "SELECT 'ab' LIKE 'abC%';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.34",</div>
                  <div>+        "SELECT 'abCDF' LIKE 'abC%';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.35",</div>
                  <div>+        "SELECT 'CDF' LIKE 'abC%';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+    {"1.36",</div>
                  <div>+        "SELECT 'ab' LIKE 'a_%';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.37",</div>
                  <div>+        "SELECT 'abCDF' LIKE 'a_%';",</div>
                  <div>+        {0, {1}} },</div>
                  <div>+    {"1.38",</div>
                  <div>+        "SELECT 'CDF' LIKE 'a_%';",</div>
                  <div>+        {0, {0}} },</div>
                  <div>+}</div>
                </div>
              </blockquote>
              Please, add some tests for unicode strings. (or replace
              letters in those tests with unicode letters)<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Changed existing tests a little bit.</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>+</div>
                  <div>+test:do_catchsql_set_test(like_test_cases,
                    prefix)</div>
                  <div>+</div>
                  <div>+-- Invalid testcases.</div>
                  <div>+for i, tested_string in
                    ipairs(invalid_testcases) do</div>
                  <div>+</div>
                  <div>+    -- We should raise an error in case</div>
                  <div>+    -- pattern contains invalid characters.</div>
                  <div>+</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>+</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>+</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>+</div>
                  <div>+    -- Just skipping if row value predicand
                    contains invalid character.</div>
                </div>
              </blockquote>
              What the predicand is? Is it a typo?<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>You can find it in ANSI SQL: <row value predicand>.</div>
          <div>Basically it's just operand inside of a predicate.</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF">
              <blockquote type="cite">
                <div dir="ltr">
                  <div>+</div>
                  <div>+    test_name = prefix .. "5." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'ab" .. tested_string
                    .. "' LIKE 'abc';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "6." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'abc" .. tested_string
                    .. "' LIKE 'abc';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "7." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'ab" .. tested_string
                    .. "c' LIKE 'abc';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+end</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_itself = "SELECT 'abc' LIKE 'ab"
                    .. tested_string .. "';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "9." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'abc' LIKE 'abc" ..
                    tested_string .. "';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "10." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'abc' LIKE 'ab" ..
                    tested_string .. "c';"</div>
                  <div>+    test:do_execsql_test(test_name,<span style="white-space:pre-wrap">  </span>test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "11." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'ab" .. tested_string
                    .. "' LIKE 'abc';"</div>
                  <div>+    test:do_execsql_test(test_name,<span style="white-space:pre-wrap">  </span>test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "12." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'abc" .. tested_string
                    .. "' LIKE 'abc';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+</div>
                  <div>+    test_name = prefix .. "13." .. tostring(i)</div>
                  <div>+    test_itself = "SELECT 'ab" .. tested_string
                    .. "c' LIKE 'abc';"</div>
                  <div>+    test:do_execsql_test(test_name, test_itself,
                    {0})</div>
                  <div>+end</div>
                  <div>+</div>
                  <div>+test:finish_test()</div>
                </div>
              </blockquote>
              Why I cannot find a test of `GLOB`? Even if we delete it
              in the future, it should be tested. You can write much
              less tests for glob.</div>
          </blockquote>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div bgcolor="#FFFFFF"> E.g. this<br>
              ```<br>
              select '1' glob '[0-4]';<br>
              ```<br>
              somewhy returns 0.</div>
          </blockquote>
          <div><br>
          </div>
          <div>
            <div
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial"> </div>
            <div
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">I
              actually don't think that operator that is going to be
              deleted in a few days should be tested.</div>
            <div
style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">It's
              just useless and redundant code.</div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>