-      "ESCAPE expression must be a single character",
+      "ESCAPE expression must be a"
+      " single character",
Do not split error messages at the middle of a sentence. It makes errors ungreppable.
Make it <80 somehow different.


Have already been discussed in this thread.
I suppose that we concluded to try to fit into 80 and split the string only
in case it is impossible.

I don’t think so. Anyways, Alexander could you please give your thoughts?
Discussed with Nikita, Alexander, Vladimir, Kirill... Conclusion: use `const char temp variable` if possible.
like this:
```
        const char *const err_msg =
            "ESCAPE expression must be a single character";
        if (sqlite3Utf8CharLen((char *)zEsc, -1) != 1) {
            sqlite3_result_error(context,
                         err_msg,
                         -1);
            return;
```

If it does not help (but it is) split the message.
diff --git a/test/sql-tap/e_expr.test.lua b/test/sql-tap/e_expr.test.lua
index 162026845..0d69e8535 100755
--- a/test/sql-tap/e_expr.test.lua
+++ b/test/sql-tap/e_expr.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(11521)
+test:plan(10647)
 
 --!./tcltestrunner.lua
 -- 2010 July 16
@@ -77,7 +77,7 @@ local operations = {
     {"<>", "ne1"},
     {"!=", "ne2"},
     {"IS", "is"},
-    {"LIKE", "like"},
+--    {"LIKE", "like"},
     {"AND", "and"},
     {"OR", "or"},
     {"MATCH", "match"},
@@ -96,8 +96,9 @@ operations = {
     {"<<", ">>", "&", "|"},
     {"<", "<=", ">", ">="},
 -- Another NOTE: MATCH & REGEXP aren't supported in Tarantool &
--- are waiting for their hour.
-    {"=", "==", "!=", "<>", "LIKE"}, --"MATCH", "REGEXP"},
+--               are waiting for their hour, don't confuse them
+--               being commented with commenting of "LIKE".
+    {"=", "==", "!=", "<>"}, --"LIKE"}, --"MATCH", "REGEXP"},
Delete Like. No one returns here.

It’s a table of all of the operators thus I think it still worth leaving it there.
Who knows, it may be that someone will revive tests for LIKE.
Delete Like. No one returns here.
We do not need a garbage. Like is not relevant anymore for this test.

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