From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 444C670152; Thu, 2 Dec 2021 11:32:57 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 444C670152 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1638433977; bh=K8Ic44H8pnNHiX7RGyCTNYvwXnTqNBomuoy/SnckcI4=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=LIv4g5/T/wp0SwnClpJqm46d8Dg6h/95TR38Xa/wTzoBxYRHvpaRHBURFTUhgw23O b/IAEtlC53cr14WNay/DOcQNk5sCiEwLSqMLk1wfcW0zUOvagIRcN1zapxfHDnMVWW JpJjhSPXLEAD9SRdFaBY7OcO0zcmmSukYyJxpQ/0= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 7739670152 for ; Thu, 2 Dec 2021 11:32:55 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 7739670152 Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1mshWQ-00083o-Eu; Thu, 02 Dec 2021 11:32:54 +0300 Date: Thu, 2 Dec 2021 11:32:53 +0300 To: Vladislav Shpilevoy Cc: tarantool-patches@dev.tarantool.org Message-ID: <20211202083253.GA8207@tarantool.org> References: <20211125083336.GA56448@tarantool.org> <819eff36-2d59-3328-e442-10703dbbda99@tarantool.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <819eff36-2d59-3328-e442-10703dbbda99@tarantool.org> X-4EC0790: 10 X-7564579A: EEAE043A70213CC8 X-77F55803: 4F1203BC0FB41BD93822B471089FF64D57D2D9679C7A7861B82AB5CE2FA20EEC182A05F538085040B5706E4141A2A96E0BE013DDCFFFA26326DD507F90BEE3A779AE2E171D44AE6F X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE70C6BE81AD14BE2BFEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006371B0187663A04449C8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D843F09BF2842067D215A5392ECFC155F2117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BAA867293B0326636D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B6B1CFA6D474D4A6A4089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: 0D63561A33F958A5CB235279FF33193B680A25C68BBCC0670876E3E42E58723CD59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA759F66ED85EB5F25FD410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34A150564C13026C188BE59DBFF098BF742A9DDC75A7E23DEA2DC0468EEB02C4FFD42B3652FD8EC09F1D7E09C32AA3244CB08641C8778985F426E4D7094DC1087C8A6D4CC6FBFAC251729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojMMFVqzO9sR10eeVstKoRkg== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5DE03D098AE205AB5D0BE3F06C1376831E83D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH v1 1/2] sql: properly check bind variable names X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Mergen Imeev via Tarantool-patches Reply-To: Mergen Imeev Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi! Thank you for the review! And I'm sorry for such poor quality of my self-review this time. I will try to avoid this in future. My asnwers, diff and new patch below. On Tue, Nov 30, 2021 at 11:02:40PM +0100, Vladislav Shpilevoy wrote: > Thanks for the fixes! > > >>> diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c > >>> index eb169aeb8..74a98c550 100644 > >>> --- a/src/box/sql/expr.c > >>> +++ b/src/box/sql/expr.c > >>> @@ -1314,6 +1314,52 @@ sqlExprAssignVarNumber(Parse * pParse, Expr * pExpr, u32 n) > >>> } > >>> } > >>> > >>> +struct Expr * > >>> +expr_variable(struct Parse *parse, struct Token *spec, struct Token *id) > >> > >> 1. You might want to call it expr_new_variable(). Or sql_expr_new_variable(). > >> To be consistent with our naming policy for constructors allocating memory > >> and for consistency with with sql_expr_new_column(), sql_expr_new(), > >> sql_expr_new_dequoted(), sql_expr_new_named(), sql_expr_new_anon(). > >> > > Thank you! I renamed it to expr_new_variable(). I believe we should drop 'sql_' > > prefix for functions that only accessible in SQL. > > It would work for static functions. But if a function is visible in other > modules as a symbol, then you would get a conflict during linking if we > ever introduce another 'struct expr' somewhere. Even if they do not interest > anywhere in the code. However I don't mind leaving it as is. It can be fixed > later if ever needed. > I agree. However, I think we need to rework all the places where BOX uses internal SQL functions and structures. In this case, the struct expr should never be available in the BOX, so there should be no conflicts. > See 5 comments below. > > > diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c > > index eb169aeb8..8ff01dd33 100644 > > --- a/src/box/sql/expr.c > > +++ b/src/box/sql/expr.c > > @@ -1314,6 +1314,59 @@ sqlExprAssignVarNumber(Parse * pParse, Expr * pExpr, u32 n) > > } > > } > > > > +struct Expr * > > +expr_new_variable(struct Parse *parse, const struct Token *spec, > > + const struct Token *id) > > +{ > > + assert(spec != 0 && spec->n == 1); > > + uint32_t len = 1; > > + if (parse->parse_only) { > > + diag_set(ClientError, ER_SQL_PARSER_GENERIC_WITH_POS, > > + parse->line_count, parse->line_pos, > > + "bindings are not allowed in DDL"); > > + parse->is_aborted = true; > > + return NULL; > > + } > > + if (id != NULL) { > > + assert(spec->z[0] != '?'); > > + if (id->z - spec->z != 1) { > > + diag_set(ClientError, ER_SQL_UNKNOWN_TOKEN, > > + parse->line_count, spec->z - parse->zTail + 1, > > + spec->n, spec->z); > > + parse->is_aborted = true; > > + return NULL; > > + } > > + if (spec->z[0] == '#' && (id != NULL && sqlIsdigit(id->z[0]))) { > > 1. You already checked for 'id != NULL' several lines above. Also you > don't need () around the second &&. > Thanks, fixed. > > + diag_set(ClientError, ER_SQL_SYNTAX_NEAR_TOKEN, > > + parse->line_count, spec->n, spec->z); > > + parse->is_aborted = true; > > + return NULL; > > + } > > + len += id->n; > > + } > > + struct Expr *expr = sqlDbMallocRawNN(parse->db, > > + sizeof(*expr) + len + 1); > > 2. sql_expr_new_empty(). > Fixed. > > + if (expr == NULL) { > > + parse->is_aborted = true; > > + return NULL; > > + } > > diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y > > index ee319d5ad..15f6223b0 100644 > > --- a/src/box/sql/parse.y > > +++ b/src/box/sql/parse.y > > @@ -1019,20 +1010,16 @@ idlist(A) ::= nm(Y). { > > p->flags = EP_Leaf; > > p->iAgg = -1; > > p->u.zToken = (char*)&p[1]; > > - if (op != TK_VARIABLE) { > > - int rc = sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); > > - if (rc > name_sz) { > > - name_sz = rc; > > - p = sqlDbReallocOrFree(pParse->db, p, sizeof(*p) + name_sz); > > - if (p == NULL) > > - goto tarantool_error; > > - p->u.zToken = (char *) &p[1]; > > - if (sql_normalize_name(p->u.zToken, name_sz, t.z, t.n) > name_sz) > > - unreachable(); > > + int rc = sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); > > + if (rc > name_sz) { > > + name_sz = rc; > > + p = sqlDbReallocOrFree(pParse->db, p, sizeof(*p) + name_sz); > > + if (p == NULL) { > > + sqlDbFree(pParse->db, p); > > 3. From the name sqlDbReallocOrFree() it looks like 'p' is already > freed. Also it is NULL here anyway, what makes sqlDbFree() nop. > Fixed. > > + pParse->is_aborted = true; > > 4. You will get a crash below, because p is NULL but you dereference > it right afterwards. > Fixed. > > } > > - } else { > > - memcpy(p->u.zToken, t.z, t.n); > > - p->u.zToken[t.n] = 0; > > + p->u.zToken = (char *) &p[1]; > > 5. Don't need whitespace after cast operator. > Fixed. > > + sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); > > } Diff: diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 8ff01dd33..e832984c3 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -1318,7 +1318,7 @@ struct Expr * expr_new_variable(struct Parse *parse, const struct Token *spec, const struct Token *id) { - assert(spec != 0 && spec->n == 1); + assert(spec != NULL && spec->n == 1); uint32_t len = 1; if (parse->parse_only) { diag_set(ClientError, ER_SQL_PARSER_GENERIC_WITH_POS, @@ -1336,7 +1336,7 @@ expr_new_variable(struct Parse *parse, const struct Token *spec, parse->is_aborted = true; return NULL; } - if (spec->z[0] == '#' && (id != NULL && sqlIsdigit(id->z[0]))) { + if (spec->z[0] == '#' && sqlIsdigit(id->z[0])) { diag_set(ClientError, ER_SQL_SYNTAX_NEAR_TOKEN, parse->line_count, spec->n, spec->z); parse->is_aborted = true; @@ -1344,15 +1344,8 @@ expr_new_variable(struct Parse *parse, const struct Token *spec, } len += id->n; } - struct Expr *expr = sqlDbMallocRawNN(parse->db, - sizeof(*expr) + len + 1); - if (expr == NULL) { - parse->is_aborted = true; - return NULL; - } - memset(expr, 0, sizeof(*expr)); + struct Expr *expr = sql_expr_new_empty(parse->db, TK_VARIABLE, len + 1); expr->type = FIELD_TYPE_BOOLEAN; - expr->op = TK_VARIABLE; expr->flags = EP_Leaf; expr->iAgg = -1; expr->u.zToken = (char *)(expr + 1); diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index 15f6223b0..ecc7f7778 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -1015,10 +1015,10 @@ idlist(A) ::= nm(Y). { name_sz = rc; p = sqlDbReallocOrFree(pParse->db, p, sizeof(*p) + name_sz); if (p == NULL) { - sqlDbFree(pParse->db, p); pParse->is_aborted = true; + return; } - p->u.zToken = (char *) &p[1]; + p->u.zToken = (char *)&p[1]; sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); } #if SQL_MAX_EXPR_DEPTH>0 New patch: commit 9a4bfea66a2e76340e96dff4ba0b04fe54f9d681 Author: Mergen Imeev Date: Thu Nov 18 11:02:20 2021 +0300 sql: properly check bind variable names After this patch, variable names will have to follow the rules defined for identifiers in SQL. This essentially means that the number will no longer be used as the first character of the bind variable name. Part of #4763 diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index eb169aeb8..e832984c3 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -1314,6 +1314,52 @@ sqlExprAssignVarNumber(Parse * pParse, Expr * pExpr, u32 n) } } +struct Expr * +expr_new_variable(struct Parse *parse, const struct Token *spec, + const struct Token *id) +{ + assert(spec != NULL && spec->n == 1); + uint32_t len = 1; + if (parse->parse_only) { + diag_set(ClientError, ER_SQL_PARSER_GENERIC_WITH_POS, + parse->line_count, parse->line_pos, + "bindings are not allowed in DDL"); + parse->is_aborted = true; + return NULL; + } + if (id != NULL) { + assert(spec->z[0] != '?'); + if (id->z - spec->z != 1) { + diag_set(ClientError, ER_SQL_UNKNOWN_TOKEN, + parse->line_count, spec->z - parse->zTail + 1, + spec->n, spec->z); + parse->is_aborted = true; + return NULL; + } + if (spec->z[0] == '#' && sqlIsdigit(id->z[0])) { + diag_set(ClientError, ER_SQL_SYNTAX_NEAR_TOKEN, + parse->line_count, spec->n, spec->z); + parse->is_aborted = true; + return NULL; + } + len += id->n; + } + struct Expr *expr = sql_expr_new_empty(parse->db, TK_VARIABLE, len + 1); + expr->type = FIELD_TYPE_BOOLEAN; + expr->flags = EP_Leaf; + expr->iAgg = -1; + expr->u.zToken = (char *)(expr + 1); + expr->u.zToken[0] = spec->z[0]; + if (id != NULL) + memcpy(expr->u.zToken + 1, id->z, id->n); + expr->u.zToken[len] = '\0'; + assert(SQL_MAX_EXPR_DEPTH > 0); + expr->nHeight = 1; + + sqlExprAssignVarNumber(parse, expr, len); + return expr; +} + /* * Recursively delete an expression tree. */ diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index ee319d5ad..ecc7f7778 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -1002,15 +1002,6 @@ idlist(A) ::= nm(Y). { case TK_UNKNOWN: p->type = FIELD_TYPE_BOOLEAN; break; - case TK_VARIABLE: - /* - * For variables we set BOOLEAN type since - * unassigned bindings will be replaced - * with NULL automatically, i.e. without - * explicit call of sql_bind_*(). - */ - p->type = FIELD_TYPE_BOOLEAN; - break; default: p->type = FIELD_TYPE_SCALAR; break; @@ -1019,20 +1010,16 @@ idlist(A) ::= nm(Y). { p->flags = EP_Leaf; p->iAgg = -1; p->u.zToken = (char*)&p[1]; - if (op != TK_VARIABLE) { - int rc = sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); - if (rc > name_sz) { - name_sz = rc; - p = sqlDbReallocOrFree(pParse->db, p, sizeof(*p) + name_sz); - if (p == NULL) - goto tarantool_error; - p->u.zToken = (char *) &p[1]; - if (sql_normalize_name(p->u.zToken, name_sz, t.z, t.n) > name_sz) - unreachable(); + int rc = sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); + if (rc > name_sz) { + name_sz = rc; + p = sqlDbReallocOrFree(pParse->db, p, sizeof(*p) + name_sz); + if (p == NULL) { + pParse->is_aborted = true; + return; } - } else { - memcpy(p->u.zToken, t.z, t.n); - p->u.zToken[t.n] = 0; + p->u.zToken = (char *)&p[1]; + sql_normalize_name(p->u.zToken, name_sz, t.z, t.n); } #if SQL_MAX_EXPR_DEPTH>0 p->nHeight = 1; @@ -1042,9 +1029,6 @@ idlist(A) ::= nm(Y). { pOut->zStart = t.z; pOut->zEnd = &t.z[t.n]; return; -tarantool_error: - sqlDbFree(pParse->db, p); - pParse->is_aborted = true; } } @@ -1087,30 +1071,17 @@ term(A) ::= INTEGER(X). { A.zEnd = X.z + X.n; if( A.pExpr ) A.pExpr->flags |= EP_Leaf; } -expr(A) ::= VARIABLE(X). { - Token t = X; - if (pParse->parse_only) { - spanSet(&A, &t, &t); - diag_set(ClientError, ER_SQL_PARSER_GENERIC_WITH_POS, pParse->line_count, - pParse->line_pos, "bindings are not allowed in DDL"); - pParse->is_aborted = true; - A.pExpr = NULL; - } else if (!(X.z[0]=='#' && sqlIsdigit(X.z[1]))) { - u32 n = X.n; - spanExpr(&A, pParse, TK_VARIABLE, X); - if (A.pExpr->u.zToken[0] == '?' && n > 1) { - diag_set(ClientError, ER_SQL_SYNTAX_NEAR_TOKEN, pParse->line_count, t.n, t.z); - pParse->is_aborted = true; - } else { - sqlExprAssignVarNumber(pParse, A.pExpr, n); - } - }else{ - assert( t.n>=2 ); - spanSet(&A, &t, &t); - diag_set(ClientError, ER_SQL_SYNTAX_NEAR_TOKEN, pParse->line_count, t.n, t.z); - pParse->is_aborted = true; - A.pExpr = NULL; - } +expr(A) ::= VARNUM(X). { + A.pExpr = expr_new_variable(pParse, &X, NULL); + spanSet(&A, &X, &X); +} +expr(A) ::= VARIABLE(X) id(Y). { + A.pExpr = expr_new_variable(pParse, &X, &Y); + spanSet(&A, &X, &Y); +} +expr(A) ::= VARIABLE(X) INTEGER(Y). { + A.pExpr = expr_new_variable(pParse, &X, &Y); + spanSet(&A, &X, &Y); } expr(A) ::= expr(A) COLLATE id(C). { A.pExpr = sqlExprAddCollateToken(pParse, A.pExpr, &C, 1); diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index dcd71e5bd..1c469e3fc 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -2617,6 +2617,17 @@ Expr *sqlExprFunction(Parse *, ExprList *, Token *); void sqlExprAssignVarNumber(Parse *, Expr *, u32); ExprList *sqlExprListAppendVector(Parse *, ExprList *, IdList *, Expr *); +/** + * Parse tokens as a name or a position of bound variable. + * + * @param parse Parse context. + * @param spec Special symbol for bound variable. + * @param id Name or position number of bound variable. + */ +struct Expr * +expr_new_variable(struct Parse *parse, const struct Token *spec, + const struct Token *id); + /** * Set the sort order for the last element on the given ExprList. * diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c index f2d5a2df5..8bc519b9d 100644 --- a/src/box/sql/tokenize.c +++ b/src/box/sql/tokenize.c @@ -58,8 +58,8 @@ #define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ #define CC_ID 2 /* unicode characters usable in IDs */ #define CC_DIGIT 3 /* Digits */ -#define CC_DOLLAR 4 /* '$' */ -#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ +/** SQL variables: '@', '#', ':', and '$'. */ +#define CC_VARALPHA 5 #define CC_VARNUM 6 /* '?'. Numeric SQL variables */ #define CC_SPACE 7 /* Space characters */ #define CC_QUOTE 8 /* '\''. String literals */ @@ -90,7 +90,7 @@ static const char sql_ascii_class[] = { /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ /* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 28, 7, 7, 7, 27, 27, /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 2x */ 7, 15, 9, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, +/* 2x */ 7, 15, 9, 5, 5, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, /* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 29, 27, 30, 27, 1, @@ -184,7 +184,7 @@ int sql_token(const char *z, int *type, bool *is_reserved) { *is_reserved = false; - int i, n; + int i; char c, delim; /* Switch on the character-class of the first byte * of the token. See the comment on the CC_ defines @@ -369,23 +369,11 @@ sql_token(const char *z, int *type, bool *is_reserved) } return i; case CC_VARNUM: - *type = TK_VARIABLE; - for (i = 1; sqlIsdigit(z[i]); i++) { - } - return i; - case CC_DOLLAR: + *type = TK_VARNUM; + return 1; case CC_VARALPHA: - n = 0; *type = TK_VARIABLE; - for (i = 1; (c = z[i]) != 0; i++) { - if (IdChar(c)) - n++; - else - break; - } - if (n == 0) - *type = TK_ILLEGAL; - return i; + return 1; case CC_KYWD: for (i = 1; sql_ascii_class[*(unsigned char*)(z+i)] <= CC_KYWD; i++) { diff --git a/test/sql-tap/bind.test.lua b/test/sql-tap/bind.test.lua new file mode 100755 index 000000000..aaf14a44d --- /dev/null +++ b/test/sql-tap/bind.test.lua @@ -0,0 +1,15 @@ +#!/usr/bin/env tarantool +local test = require("sqltester") +test:plan(1) + +-- Make sure that bind variable names cannot start with a number. +test:do_test( + "bind-1", + function() + local res = {pcall(box.execute, [[SELECT @1asd;]], {{['@1asd'] = 123}})} + return {tostring(res[3])} + end, { + "At line 1 at or near position 9: unrecognized token '1asd'" + }) + +test:finish_test() diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua index f207d3e92..204e070d2 100755 --- a/test/sql-tap/misc1.test.lua +++ b/test/sql-tap/misc1.test.lua @@ -1052,7 +1052,7 @@ test:do_catchsql_test( select''like''like''like#0; ]], { -- - 1, [[Syntax error at line 1 near '#0']] + 1, [[Syntax error at line 1 near '#']] -- }) @@ -1062,7 +1062,7 @@ test:do_catchsql_test( VALUES(0,0x0MATCH#0; ]], { -- - 1, [[Syntax error at line 1 near '#0']] + 1, [[Syntax error at line 1 near '#']] -- }) diff --git a/test/sql/iproto.result b/test/sql/iproto.result index 6212aa0c0..5a424596e 100644 --- a/test/sql/iproto.result +++ b/test/sql/iproto.result @@ -351,7 +351,7 @@ cn:execute('drop table if exists test3') -- cn:execute('select ?1, ?2, ?3', {1, 2, 3}) --- -- error: Syntax error at line 1 near '?1' +- error: Syntax error at line 1 near '1' ... cn:execute('select $name, $name2', {1, 2}) ---