<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">ср, 18 июл. 2018 г. в 18:53, Alex Khatskevich <<a href="mailto:avkhatskevich@tarantool.org">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">
    Once you have fixed comments, please apply a new full diff at the
    end of email, to<br>
    continue review process.<br>
    Answer with a full diff to this email please (just paste as a plain
    text output of `git diff` command)<br>
    <br>
    <div class="gmail-m_-7042709502264890074moz-cite-prefix">On 18.07.2018 18:24, Nikita Tatunov
      wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr"><br>
        <div class="gmail_quote">
          <div>Fixed it.</div>
          <div><br>
          </div>
          <div>Yeah, you're right. Fixed it.</div>
          <div> </div>
          <div>Isn't actual with the fix.</div>
          <div><br>
          </div>
          <div>Yeah, sure. </div>
        </div>
      </div>
    </blockquote>
    <br></div></blockquote><div><br></div><div>Sorry. Here it is:<br><br><div>diff --git a/src/box/sql/func.c b/src/box/sql/func.c</div><div>index c06e3bd..a7f7c17 100644</div><div>--- a/src/box/sql/func.c</div><div>+++ b/src/box/sql/func.c</div><div>@@ -617,13 +617,15 @@ struct compareInfo {</div><div> <span style="white-space:pre">        </span>u8 noCase;<span style="white-space:pre">           </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 macro returns</div><div>+ * UTF-8 code of character and pushes pointer to the next symbol</div><div>+ * in the string. 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">     </span>ucnv_getNextUChar(pUtf8conv, &s, e, &status) : 0)</div><div>+</div><div>+#define SQL_END_OF_STRING       0</div><div> </div><div> static const struct compareInfo globInfo = { '*', '?', '[', 0 };</div><div> </div><div>@@ -698,29 +700,27 @@ patternCompare(const char * pattern,<span style="white-space:pre">   </span>/* The glob pattern */</div><div> <span style="white-space:pre">      </span>const char * string_end = string + strlen(string);</div><div> <span style="white-space:pre">  </span>UErrorCode status = U_ZERO_ERROR;</div><div> </div><div>-<span style="white-space:pre">   </span>while (pattern < pattern_end){</div><div>-<span style="white-space:pre">            </span>c = Utf8Read(pattern, pattern_end);</div><div>+<span style="white-space:pre">  </span>while ((c = Utf8Read(pattern, pattern_end))) {</div><div> <span style="white-space:pre">              </span>if (c == matchAll) {<span style="white-space:pre"> </span>/* Match "*" */</div><div> <span style="white-space:pre">                   </span>/* Skip over multiple "*" characters in the pattern.  If there</div><div> <span style="white-space:pre">                   </span> * are also "?" characters, skip those as well, but consume a</div><div> <span style="white-space:pre">                     </span> * single character of the input string for each "?" skipped</div><div> <span style="white-space:pre">                      </span> */</div><div>-<span style="white-space:pre">                  </span>while (pattern < pattern_end){</div><div>-<span style="white-space:pre">                            </span>c = Utf8Read(pattern, pattern_end);</div><div>+<span style="white-space:pre">                  </span>while ((c = Utf8Read(pattern, pattern_end))) {</div><div> <span style="white-space:pre">                              </span>if (c != matchAll && c != matchOne)</div><div> <span style="white-space:pre">                                 </span>break;</div><div>-<span style="white-space:pre">                               </span>if (c == matchOne</div><div>-<span style="white-space:pre">                            </span>    && Utf8Read(string, string_end) == 0) {</div><div>+<span style="white-space:pre">                                </span>if (c == matchOne &&</div><div>+<span style="white-space:pre">                         </span>    Utf8Read(string, string_end) ==</div><div>+<span style="white-space:pre">                                </span>    SQL_END_OF_STRING)</div><div> <span style="white-space:pre">                                    </span>return SQLITE_NOWILDCARDMATCH;</div><div>-<span style="white-space:pre">                               </span>}</div><div> <span style="white-space:pre">                   </span>}</div><div> <span style="white-space:pre">                   </span>/* "*" at the end of the pattern matches */</div><div>-<span style="white-space:pre">                        </span>if (pattern == pattern_end)</div><div>+<span style="white-space:pre">                  </span>if (c == SQL_END_OF_STRING)</div><div> <span style="white-space:pre">                         </span>return SQLITE_MATCH;</div><div> <span style="white-space:pre">                        </span>if (c == matchOther) {</div><div> <span style="white-space:pre">                              </span>if (pInfo->matchSet == 0) {</div><div> <span style="white-space:pre">                                      </span>c = Utf8Read(pattern, pattern_end);</div><div>-<span style="white-space:pre">                                  </span>if (c == 0)</div><div>+<span style="white-space:pre">                                  </span>if (c == SQL_END_OF_STRING)</div><div> <span style="white-space:pre">                                         </span>return SQLITE_NOWILDCARDMATCH;</div><div> <span style="white-space:pre">                              </span>} else {</div><div> <span style="white-space:pre">                                    </span>/* "[...]" immediately follows the "*".  We have to do a slow</div><div>@@ -782,7 +782,7 @@ patternCompare(const char * pattern,<span style="white-space:pre">    </span>/* The glob pattern */</div><div> <span style="white-space:pre">              </span>if (c == matchOther) {</div><div> <span style="white-space:pre">                      </span>if (pInfo->matchSet == 0) {</div><div> <span style="white-space:pre">                              </span>c = Utf8Read(pattern, pattern_end);</div><div>-<span style="white-space:pre">                          </span>if (c == 0)</div><div>+<span style="white-space:pre">                          </span>if (c == SQL_END_OF_STRING)</div><div> <span style="white-space:pre">                                 </span>return SQLITE_NOMATCH;</div><div> <span style="white-space:pre">                              </span>zEscaped = pattern;</div><div> <span style="white-space:pre">                 </span>} else {</div><div>@@ -802,7 +802,7 @@ patternCompare(const char * pattern,<span style="white-space:pre">      </span>/* The glob pattern */</div><div> <span style="white-space:pre">                                              </span>seen = 1;</div><div> <span style="white-space:pre">                                   </span>c2 = Utf8Read(pattern, pattern_end);</div><div> <span style="white-space:pre">                                </span>}</div><div>-<span style="white-space:pre">                            </span>while (c2 && c2 != ']') {</div><div>+<span style="white-space:pre">                            </span>while (c2 != SQL_END_OF_STRING && c2 != ']') {</div><div> <span style="white-space:pre">                                      </span>if (c2 == '-' && pattern[0] != ']'</div><div> <span style="white-space:pre">                                  </span>    && pattern < pattern_end</div><div> <span style="white-space:pre">                                   </span>    && prior_c > 0) {</div><div>@@ -839,7 +839,8 @@ patternCompare(const char * pattern,<span style="white-space:pre">    </span>/* The glob pattern */</div><div> <span style="white-space:pre">                      </span>    c == u_tolower(c2))</div><div> <span style="white-space:pre">                           </span>continue;</div><div> <span style="white-space:pre">           </span>}</div><div>-<span style="white-space:pre">            </span>if (c == matchOne && pattern != zEscaped && c2 != 0)</div><div>+<span style="white-space:pre">         </span>if (c == matchOne && pattern != zEscaped &&</div><div>+<span style="white-space:pre">          </span>    c2 != SQL_END_OF_STRING)</div><div> <span style="white-space:pre">                      </span>continue;</div><div> <span style="white-space:pre">           </span>return SQLITE_NOMATCH;</div><div> <span style="white-space:pre">      </span>}</div><div>diff --git a/test/sql-tap/like1.test.lua b/test/sql-tap/like1.test.lua</div><div>new file mode 100755</div><div>index 0000000..807ee65</div><div>--- /dev/null</div><div>+++ b/test/sql-tap/like1.test.lua</div><div>@@ -0,0 +1,181 @@</div><div>+#!/usr/bin/env tarantool</div><div>+test = require("sqltester")</div><div>+test:plan(16)</div><div>+</div><div>+test:do_catchsql_test(</div><div>+<span style="white-space:pre">   </span>"like-test-1.1",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>CREATE TABLE t2 (column1 INTEGER,</div><div>+<span style="white-space:pre">                            </span>     column2 VARCHAR(100),</div><div>+<span style="white-space:pre">                                </span>     column3 BLOB,</div><div>+<span style="white-space:pre">                                </span>     column4 FLOAT,</div><div>+<span style="white-space:pre">                               </span>     PRIMARY KEY (column1, column2));</div><div>+<span style="white-space:pre">             </span>INSERT INTO t2 VALUES (1, 'AB', X'4142', 5.5);</div><div>+<span style="white-space:pre">               </span>INSERT INTO t2 VALUES (1, 'CD', X'2020', 1E4);</div><div>+<span style="white-space:pre">               </span>INSERT INTO t2 VALUES (2, 'AB', X'2020', 12.34567);</div><div>+<span style="white-space:pre">          </span>INSERT INTO t2 VALUES (-1000, '', X'', 0.0);</div><div>+<span style="white-space:pre">         </span>CREATE TABLE t1 (a INT PRIMARY KEY, str VARCHAR(100));</div><div>+<span style="white-space:pre">               </span>INSERT INTO t1 VALUES (1, 'ab');</div><div>+<span style="white-space:pre">             </span>INSERT INTO t1 VALUES (2, 'abCDF');</div><div>+<span style="white-space:pre">          </span>INSERT INTO t1 VALUES (3, 'CDF');</div><div>+<span style="white-space:pre">            </span>CREATE TABLE t (s1 char(2) primary key, s2 char(2));</div><div>+<span style="white-space:pre">         </span>INSERT INTO t VALUES ('AB', 'AB');</div><div>+<span style="white-space:pre">   </span>]], {</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.1></div><div>+<span style="white-space:pre">             </span>0</div><div>+<span style="white-space:pre">            </span>-- <like-test-1.1></div><div>+<span style="white-space:pre">     </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.2",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2, column1 * column4 FROM t2 WHERE column2 LIKE '_B';</div><div>+<span style="white-space:pre">  </span>]], {</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.2></div><div>+<span style="white-space:pre">             </span>1, 'AB', 5.5, 2, 'AB', 24.69134</div><div>+<span style="white-space:pre">              </span>-- <like-test-1.2></div><div>+<span style="white-space:pre">     </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.3",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2 FROM t2 WHERE column2 LIKE '%B';</div><div>+<span style="white-space:pre">     </span>]], {</div><div>+             -- <like-test-1.3></div><div>+             1, 'AB', 2, 'AB'</div><div>+             -- <like-test-1.3></div><div>+<span style="white-space:pre">    </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.4",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2 FROM t2 WHERE column2 LIKE 'A__';</div><div>+<span style="white-space:pre">    </span>]], {</div><div>+             -- <like-test-1.4></div><div>+</div><div>+             -- <like-test-1.4></div><div>+<span style="white-space:pre">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.5",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2 FROM t2 WHERE column2 LIKE 'A_';</div><div>+<span style="white-space:pre">     </span>]], {</div><div>+             -- <like-test-1.5></div><div>+             1, 'AB', 2, 'AB'</div><div>+             -- <like-test-1.5></div><div>+<span style="white-space:pre">    </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.6",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2 FROM t2 WHERE column2 LIKE 'A';</div><div>+<span style="white-space:pre">      </span>]], {</div><div>+             -- <like-test-1.6></div><div>+</div><div>+             -- <like-test-1.6></div><div>+<span style="white-space:pre">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.7",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2 FROM t2 WHERE column2 LIKE '_';</div><div>+<span style="white-space:pre">      </span>]], {</div><div>+             -- <like-test-1.7></div><div>+</div><div>+             -- <like-test-1.7></div><div>+<span style="white-space:pre">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.8",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT * FROM t WHERE s1 LIKE '%A';</div><div>+<span style="white-space:pre">  </span>]], {</div><div>+             -- <like-test-1.8></div><div>+</div><div>+             -- <like-test-1.8></div><div>+<span style="white-space:pre">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.9",</div><div>+<span style="white-space:pre">   </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT * FROM t WHERE s1 LIKE '%C';</div><div>+<span style="white-space:pre">  </span>]], {</div><div>+             -- <like-test-1.9></div><div>+</div><div>+             -- <like-test-1.9></div><div>+<span style="white-space:pre">        </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.10",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT * FROM t1 WHERE str LIKE '%df';</div><div>+<span style="white-space:pre">       </span>]], {</div><div>+             -- <like-test-1.10></div><div>+             2, 'abCDF', 3, 'CDF'</div><div>+             -- <like-test-1.10></div><div>+<span style="white-space:pre">      </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.11",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT * FROM t1 WHERE str LIKE 'a_';</div><div>+<span style="white-space:pre">        </span>]], {</div><div>+             -- <like-test-1.11></div><div>+             1, 'ab'</div><div>+             -- <like-test-1.11></div><div>+<span style="white-space:pre">   </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.12",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT column1, column2 FROM t2 WHERE column2 LIKE '__';</div><div>+<span style="white-space:pre">     </span>]], {</div><div>+             -- <like-test-1.12></div><div>+             1, 'AB', 1, 'CD', 2, 'AB'</div><div>+             -- <like-test-1.12></div><div>+<span style="white-space:pre"> </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.13",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT str FROM t1 WHERE str LIKE 'ab%';</div><div>+<span style="white-space:pre">     </span>]], {</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.13></div><div>+<span style="white-space:pre">            </span>'ab', 'abCDF'</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.13></div><div>+<span style="white-space:pre">    </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.14",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT str FROM t1 WHERE str LIKE 'abC%';</div><div>+<span style="white-space:pre">    </span>]], {</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.14></div><div>+<span style="white-space:pre">            </span>'abCDF'</div><div>+<span style="white-space:pre">              </span>-- <like-test-1.14></div><div>+<span style="white-space:pre">    </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.15",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>SELECT str FROM t1 WHERE str LIKE 'a_%';</div><div>+<span style="white-space:pre">     </span>]], {</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.15></div><div>+<span style="white-space:pre">            </span>'ab', 'abCDF'</div><div>+<span style="white-space:pre">                </span>-- <like-test-1.15></div><div>+<span style="white-space:pre">    </span>})</div><div>+</div><div>+test:do_execsql_test(</div><div>+<span style="white-space:pre">      </span>"like-test-1.16",</div><div>+<span style="white-space:pre">  </span>[[</div><div>+<span style="white-space:pre">           </span>DROP TABLE t1;</div><div>+<span style="white-space:pre">               </span>DROP TABLE t2;</div><div>+<span style="white-space:pre">               </span>DROP TABLE t;</div><div>+<span style="white-space:pre">        </span>]], {</div><div>+             -- <like-test-1.16></div><div>+</div><div>+             -- <like-test-1.16></div><div>+<span style="white-space:pre">      </span>})</div><div>+</div><div>+test:finish_test()</div> </div></div></div>