From: "n.pettik" <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: Imeev Mergen <imeevma@tarantool.org> Subject: [tarantool-patches] Re: [PATCH v4 7/8] sql: rework semantic errors Date: Fri, 15 Mar 2019 18:49:20 +0300 [thread overview] Message-ID: <53DBABF2-8730-4FF6-9C23-64BF3F9986D1@tarantool.org> (raw) In-Reply-To: <6dca562ff5163f5579f45d175b6cf188db52a09f.1552494059.git.imeevma@gmail.com> > diff --git a/src/box/errcode.h b/src/box/errcode.h > index 7764aa3..a0d8f4ae 100644 > --- a/src/box/errcode.h > +++ b/src/box/errcode.h > @@ -122,7 +122,7 @@ struct errcode_record { > /* 67 */_(ER_REPLICA_ID_IS_RESERVED, "Can't initialize replica id with a reserved value %u") \ > /* 68 */_(ER_INVALID_ORDER, "Invalid LSN order for instance %u: previous LSN = %llu, new lsn = %llu") \ > /* 69 */_(ER_MISSING_REQUEST_FIELD, "Missing mandatory field '%s' in request") \ > - /* 70 */_(ER_IDENTIFIER, "Invalid identifier '%s' (expected printable symbols only)") \ > + /* 70 */_(ER_IDENTIFIER, "Invalid identifier '%s' (expected printable symbols only or it is too long)") \ > /* 71 */_(ER_DROP_FUNCTION, "Can't drop function %u: %s") \ > /* 72 */_(ER_ITERATOR_TYPE, "Unknown iterator type '%s'") \ > /* 73 */_(ER_REPLICA_MAX, "Replica count limit reached: %u") \ > @@ -240,6 +240,13 @@ struct errcode_record { > /*185 */_(ER_SQL_UNKNOWN_TOKEN, "Syntax error: unrecognized token: '%.*s'") \ > /*186 */_(ER_SQL_PARSER_GENERIC, "%s") \ > /*187 */_(ER_SQL_ANALYZE_ARGUMENT, "ANALYZE statement argument %s is not a base table") \ > + /*188 */_(ER_SQL_COLUMN_COUNT_MAX, "Failed to create space '%s': space column count %d exceeds the limit (%d)") \ > + /*189 */_(ER_HEX_LITERAL_MAX, "Hex literal %s%s length %d exceeds the supported limit (%d)") \ > + /*190 */_(ER_INT_LITERAL_MAX, "Integer literal %s%s exceeds the supported range %lld - %lld") \ > + /*191 */_(ER_SQL_PARSER_LIMIT, "%s%.*s %d exceeds the limit (%d)") \ You use auxiliary params only in one place. I guess it is worth removing them. > + /*192 */_(ER_INDEX_DEF, "%s prohibited in an index definition") \ Why not ER_UNSUPPORTED? ER_INDEX_DEF -> ER_INDEX_DEF_UNSUPPORTED Also, quite unnatural message pattern: it is hard to understand diags like: diag_set(ClientError, ER_INDEX_DEF, "Parameter markers are"); > + /*193 */_(ER_CHECK_CONSTRAINT_DEF, "%s prohibited in a CHECK constraint definition") \ The same question. ER_CHECK_CONSTRAINT_DEF -> ER_CK_DEF_UNSUPPORTED > + /*194 */_(ER_PRIMARY_KEY_DEF, "Expressions are prohibited in a primary key definition") \ Just substitute it with ER_INDEX_DEF_UNSUPPORTED: expressions are prohibited in secondary index definition as well. > > /* > * !IMPORTANT! Please follow instructions at start of the file > diff --git a/src/box/sql/build.c b/src/box/sql/build.c > index 0c06555..26434b1 100644 > --- a/src/box/sql/build.c > +++ b/src/box/sql/build.c > @@ -267,14 +267,14 @@ int > sqlCheckIdentifierName(Parse *pParse, char *zName) > { > ssize_t len = strlen(zName); > - > - if (len > BOX_NAME_MAX || identifier_check(zName, len) != 0) { > - sqlErrorMsg(pParse, > - "identifier name is invalid: %s", > - zName); > - return SQL_ERROR; > + if (len <= BOX_NAME_MAX && identifier_check(zName, len) == 0) > + return SQL_OK; return 0; > + if (len > BOX_NAME_MAX) { > + diag_set(ClientError, ER_IDENTIFIER, > + tt_cstr(zName, BOX_INVALID_NAME_MAX)); > } > - return SQL_OK; > + pParse->is_aborted = true; > + return SQL_ERROR; return -1; ssize_t len = strlen(zName); - if (len <= BOX_NAME_MAX && identifier_check(zName, len) == 0) - return SQL_OK; if (len > BOX_NAME_MAX) { diag_set(ClientError, ER_IDENTIFIER, tt_cstr(zName, BOX_INVALID_NAME_MAX)); + pParse->is_aborted = true; + return -1; } - pParse->is_aborted = true; - return SQL_ERROR; + if (identifier_check(zName, len) != 0) { + pParse->is_aborted = true; + return -1; + } + return 0; > @@ -588,9 +590,9 @@ sqlAddPrimaryKey(Parse * pParse, /* Parsing context */ > if (space == NULL) > goto primary_key_exit; > if (sql_space_primary_key(space) != NULL) { > - sqlErrorMsg(pParse, > - "table \"%s\" has more than one primary key", > - space->def->name); > + diag_set(ClientError, ER_CREATE_SPACE, space->def->name, > + "too many primary keys”); too many primary keys -> primary key already exists > + pParse->is_aborted = true; > goto primary_key_exit; > } > if (pList == NULL) { > > @@ -1775,6 +1778,11 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child, > } > if (constraint_name == NULL) > goto exit_create_fk; > + if (!is_self_referenced && parent_space->def->opts.is_view) { > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, constraint_name, > + "referenced space can't be VIEW"); > + goto tnt_error; > + } This check is already processed in on_replace_dd_fk_constraint() Could you remove this check to avoid code duplication? > @@ -2942,11 +2958,8 @@ sqlSavepoint(Parse * pParse, int op, Token * pName) > return; > } > if (op == SAVEPOINT_BEGIN && > - sqlCheckIdentifierName(pParse, zName) > - != SQL_OK) { > - sqlErrorMsg(pParse, "bad savepoint name"); > + sqlCheckIdentifierName(pParse, zName) != SQL_OK) != 0 > diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c > index 87d4ed4..e8a5f0d 100644 > --- a/src/box/sql/delete.c > +++ b/src/box/sql/delete.c > @@ -157,8 +157,9 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, > goto delete_from_cleanup; > > if (trigger_list == NULL) { > - sqlErrorMsg(parse, "cannot modify %s because it is a" > - " view", space->def->name); > + diag_set(ClientError, ER_ALTER_SPACE, space->def->name, > + "it is a view”); Nit: it is a view -> space is a view (sounds better IMHO). > + parse->is_aborted = true; > goto delete_from_cleanup; > } > } > diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c > index 4193596..de06ee0 100644 > --- a/src/box/sql/expr.c > +++ b/src/box/sql/expr.c > @@ -750,15 +750,14 @@ codeVectorCompare(Parse * pParse, /* Code generator context */ > int > sqlExprCheckHeight(Parse * pParse, int nHeight) > { > - int rc = SQL_OK; > int mxHeight = pParse->db->aLimit[SQL_LIMIT_EXPR_DEPTH]; > if (nHeight > mxHeight) { > - sqlErrorMsg(pParse, > - "Expression tree is too large (maximum depth %d)", > - mxHeight); > - rc = SQL_ERROR; > + diag_set(ClientError, ER_SQL_PARSER_LIMIT, "Number of nodes "\ > + "in expression tree", 0, "", nHeight, mxHeight); > + pParse->is_aborted = true; > + return SQL_ERROR; return -1; > } > - return rc; > + return SQL_OK; return 0; > > @@ -690,9 +674,12 @@ resolveExprStep(Walker * pWalker, Expr * pExpr) > * that might change over time cannot be used > * in an index. > */ > - notValid(pParse, pNC, > - "non-deterministic functions", > - NC_IdxExpr); > + if (pNC->ncFlags & NC_IdxExpr) { > + diag_set(ClientError, ER_INDEX_DEF, > + "Non-deterministic functions "\ > + "are”); This code seems to be unreachable: functional indexes are filtered a way earlier. > @@ -754,8 +741,16 @@ resolveExprStep(Walker * pWalker, Expr * pExpr) > testcase(pExpr->op == TK_IN); > if (ExprHasProperty(pExpr, EP_xIsSelect)) { > int nRef = pNC->nRef; > - notValid(pParse, pNC, "subqueries", > - NC_IsCheck | NC_IdxExpr); > + if (pNC->ncFlags & NC_IdxExpr) { > + diag_set(ClientError, ER_INDEX_DEF, > + "Subqueries are”); The same: managed to grep this error only for ck constraint. > @@ -1042,27 +1044,34 @@ resolveCompoundOrderBy(Parse * pParse, /* Parsing context. Leave error messages > * field) then convert that term into a copy of the corresponding result set > * column. > * > - * If any errors are detected, add an error message to pParse and > - * return non-zero. Return zero if no errors are seen. > + * @param pParse Parsing context. > + * @param pSelect The SELECT statement containing the clause. > + * @param pOrderBy The ORDER BY or GROUP BY clause to be > + * processed. > + * @param is_order_by True if pOrderBy is ORDER BY, false if > + * pOrderBy is GROUP BY > + * @retval 0 On success, not 0 elsewhere. > */ > int > -sqlResolveOrderGroupBy(Parse * pParse, /* Parsing context. Leave error messages here */ > - Select * pSelect, /* The SELECT statement containing the clause */ > - ExprList * pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ > - const char *zType /* "ORDER" or "GROUP" */ > - ) > +sqlResolveOrderGroupBy(Parse *pParse, Select *pSelect, ExprList *pOrderBy, > + bool is_order_by) Why did you decide to fix code style here? Anyway, you didn't finished it (struct prefixes, param naming and so on and so forth) > { > int i; > sql *db = pParse->db; > ExprList *pEList; > struct ExprList_item *pItem; > + const char *zType = is_order_by ? "ORDER" : "GROUP"; > > if (pOrderBy == 0 || pParse->db->mallocFailed) > return 0; > > @@ -1096,22 +1105,23 @@ sqlResolveOrderGroupBy(Parse * pParse, /* Parsing context. Leave error messages > * result-set expression. Otherwise, the expression is resolved in > * the usual way - using sqlResolveExprNames(). > * > - * This routine returns the number of errors. If errors occur, then > - * an appropriate error message might be left in pParse. (OOM errors > - * excepted.) > + * @param pNC The name context of the SELECT statement. > + * @param pSelect The SELECT statement containing the clause. > + * @param pOrderBy An ORDER BY or GROUP BY clause to resolve. > + * @param is_order_by True if pOrderBy is ORDER BY, false if > + * pOrderBy is GROUP BY > + * @retval 0 On success, not 0 elsewhere. > */ > static int > -resolveOrderGroupBy(NameContext * pNC, /* The name context of the SELECT statement */ > - Select * pSelect, /* The SELECT statement holding pOrderBy */ > - ExprList * pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ > - const char *zType /* Either "ORDER" or "GROUP", as appropriate */ > - ) The same question. > +resolveOrderGroupBy(NameContext *pNC, Select *pSelect, ExprList *pOrderBy, > + bool is_order_by) > { > int i, j; /* Loop counters */ > int iCol; /* Column number */ > struct ExprList_item *pItem; /* A term of the ORDER BY clause */ > Parse *pParse; /* Parsing context */ > int nResult; /* Number of terms in the result set */ > + const char *zType = is_order_by ? "ORDER" : "GROUP"; > > if (pOrderBy == 0) > return 0; > > /* Compute the limit registers */ > computeLimitRegisters(pParse, p, labelEnd); > diff --git a/src/box/sql/update.c b/src/box/sql/update.c > index 05ceeb4..bc0ab66 100644 > --- a/src/box/sql/update.c > +++ b/src/box/sql/update.c > @@ -139,8 +139,9 @@ sqlUpdate(Parse * pParse, /* The parser context */ > goto update_cleanup; > } > if (is_view && tmask == 0) { > - sqlErrorMsg(pParse, "cannot modify %s because it is a view", > - space->def->name); > + diag_set(ClientError, ER_ALTER_SPACE, space->def->name, > + "it is a view”); -> space is a view > + pParse->is_aborted = true; > goto update_cleanup; > } > > > diff --git a/test/sql-tap/check.test.lua b/test/sql-tap/check.test.lua > index 0d8bf15..dd2de92 100755 > --- a/test/sql-tap/check.test.lua > +++ b/test/sql-tap/check.test.lua > @@ -319,7 +319,7 @@ test:do_catchsql_test( > ); > ]], { > -- <check-3.1> > - 1, "Failed to create space 'T3': subqueries prohibited in CHECK constraints" > + 1, "Failed to create space 'T3': Subqueries are prohibited in a CHECK constraint definition” Don’t use capital letter after ‘:’, it would allow you to avoid fixing tests. The same is applied to the fixes below. > -- </check-3.1> > }) > > diff --git a/test/sql-tap/colname.test.lua b/test/sql-tap/colname.test.lua > index 29fdf13..77c4280 100755 > --- a/test/sql-tap/colname.test.lua > +++ b/test/sql-tap/colname.test.lua > @@ -637,7 +637,7 @@ test:do_test( > test:do_catchsql_test( > "colname-11.1", > [[ create table t1(a INT, b INT, c INT, primary key('A'))]], > - {1, "expressions prohibited in PRIMARY KEY"}) > + {1, "Expressions are prohibited in a primary key definition"}) > > test:do_catchsql_test( > "colname-11.2", > diff --git a/test/sql-tap/default.test.lua b/test/sql-tap/default.test.lua > index 67151b0..fbe285b 100755 > --- a/test/sql-tap/default.test.lua > +++ b/test/sql-tap/default.test.lua > @@ -66,7 +66,7 @@ test:do_catchsql_test( > ); > ]], { > -- <default-1.3> > - 1, "default value of column [Y] is not constant" > + 1, "Failed to create space 'T3': default value of column is not constant” Is it possible to print also name of column (like in original version)? > diff --git a/test/sql-tap/engine.cfg b/test/sql-tap/engine.cfg > index 413dd3f..cc56592 100644 > --- a/test/sql-tap/engine.cfg > +++ b/test/sql-tap/engine.cfg > @@ -11,6 +11,9 @@ > "sort.test.lua": { > "memtx": {"engine": "memtx"} > }, > + "sql-errors.test.lua": { > + "memtx": {"engine": "memtx"} > + }, I would run this test both for vinyl and memtx.
next prev parent reply other threads:[~2019-03-15 15:49 UTC|newest] Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-13 17:03 [tarantool-patches] [PATCH v4 0/8] sql: use diag_set() for errors in SQL imeevma 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 1/8] sql: rework syntax errors imeevma 2019-03-14 18:24 ` [tarantool-patches] " n.pettik 2019-03-14 18:28 ` Imeev Mergen 2019-03-15 14:09 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 2/8] sql: set SQL parser errors via diag_set() imeevma 2019-03-14 19:26 ` [tarantool-patches] " n.pettik 2019-03-14 19:36 ` n.pettik 2019-03-18 15:06 ` Mergen Imeev 2019-03-19 9:41 ` n.pettik 2019-03-19 11:24 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 3/8] sql: replace rc with is_aborted status in struct Parse imeevma 2019-03-14 19:53 ` [tarantool-patches] " n.pettik 2019-03-18 15:28 ` Mergen Imeev 2019-03-19 9:54 ` n.pettik 2019-03-19 13:17 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 4/8] sql: remove field nErr from " imeevma 2019-03-14 19:58 ` [tarantool-patches] " n.pettik 2019-03-19 13:27 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 5/8] sql: remove field zErrMsg " imeevma 2019-03-14 22:15 ` [tarantool-patches] " n.pettik 2019-03-19 13:20 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 6/8] sql: rework three errors of "unsupported" type imeevma 2019-03-14 22:15 ` [tarantool-patches] " n.pettik 2019-03-19 13:30 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 7/8] sql: rework semantic errors imeevma 2019-03-15 15:49 ` n.pettik [this message] 2019-03-22 12:48 ` [tarantool-patches] " Mergen Imeev 2019-03-26 14:14 ` n.pettik 2019-03-26 16:56 ` Mergen Imeev 2019-03-26 18:16 ` n.pettik 2019-03-26 19:20 ` Mergen Imeev 2019-03-26 21:36 ` n.pettik 2019-03-27 6:48 ` Kirill Yukhin 2019-03-13 17:03 ` [tarantool-patches] [PATCH v4 8/8] sql: remove sqlErrorMsg() imeevma 2019-03-15 13:36 ` [tarantool-patches] " n.pettik 2019-03-25 18:47 ` Mergen Imeev 2019-03-26 13:34 ` n.pettik 2019-03-26 17:52 ` Mergen Imeev 2019-03-26 18:28 ` n.pettik 2019-03-26 19:21 ` Mergen Imeev 2019-03-26 21:36 ` n.pettik 2019-03-27 6:49 ` Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=53DBABF2-8730-4FF6-9C23-64BF3F9986D1@tarantool.org \ --to=korablev@tarantool.org \ --cc=imeevma@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH v4 7/8] sql: rework semantic errors' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox