[tarantool-patches] [PATCH v3 9/9] sql: remove sqlErrorMsg()

imeevma at tarantool.org imeevma at tarantool.org
Sat Mar 2 16:08:03 MSK 2019


This patch replaces sqlErrorMsg() by tt_sprintf() + diag_set().

Part of #3965
---
 src/box/sql/build.c             | 100 ++++++++++++++++----------
 src/box/sql/delete.c            |   7 +-
 src/box/sql/expr.c              |  85 +++++++++++++---------
 src/box/sql/insert.c            |  44 ++++++++----
 src/box/sql/parse.y             |  12 ++--
 src/box/sql/resolve.c           | 137 +++++++++++++++++++++++-------------
 src/box/sql/select.c            | 151 +++++++++++++++++++++++++---------------
 src/box/sql/sqlInt.h            |   1 -
 src/box/sql/trigger.c           |   7 +-
 src/box/sql/update.c            |  19 +++--
 src/box/sql/util.c              |  31 ---------
 src/box/sql/vdbemem.c           |   4 +-
 src/box/sql/where.c             |   4 +-
 src/box/sql/whereexpr.c         |   8 ++-
 test/sql-tap/e_select1.test.lua |  20 +++---
 test/sql-tap/null.test.lua      |   4 +-
 test/sql-tap/select1.test.lua   |   6 +-
 test/sql-tap/select3.test.lua   |   4 +-
 test/sql-tap/select4.test.lua   |   6 +-
 test/sql-tap/tkt2822.test.lua   |  30 ++++----
 test/sql-tap/with1.test.lua     |   2 +-
 21 files changed, 406 insertions(+), 276 deletions(-)

diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 64d2690..5d2a7dc 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -271,11 +271,16 @@ 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);
+	if (len > BOX_NAME_MAX) {
+		const char *err_msg =
+			tt_sprintf("identifier name is invalid: %s",
+				   tt_cstr(zName, BOX_INVALID_NAME_MAX));
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
+		return SQL_ERROR;
+	}
+	if (identifier_check(zName, len) != 0) {
+		pParse->is_aborted = true;
 		return SQL_ERROR;
 	}
 	return SQL_OK;
@@ -527,9 +532,12 @@ sqlAddDefaultValue(Parse * pParse, ExprSpan * pSpan)
 		struct space_def *def = pParse->new_space->def;
 		if (!sqlExprIsConstantOrFunction
 		    (pSpan->pExpr, db->init.busy)) {
-			sqlErrorMsg(pParse,
-					"default value of column [%s] is not constant",
-					def->fields[def->field_count - 1].name);
+			const char *err_msg =
+				tt_sprintf("default value of column [%s] is "\
+					   "not constant",
+					   def->fields[def->field_count - 1].name);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 		} else {
 			assert(def != NULL);
 			struct field_def *field =
@@ -594,9 +602,11 @@ 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);
+		const char *err_msg = tt_sprintf("table \"%s\" has more than "\
+						 "one primary key",
+						 space->def->name);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto primary_key_exit;
 	}
 	if (pList == NULL) {
@@ -642,8 +652,12 @@ sqlAddPrimaryKey(Parse * pParse,	/* Parsing context */
 		if (db->mallocFailed)
 			goto primary_key_exit;
 	} else if (autoInc) {
-		sqlErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
-				"INTEGER PRIMARY KEY or INT PRIMARY KEY");
+		const char *err_msg = tt_sprintf("AUTOINCREMENT is only "\
+						 "allowed on an INTEGER "\
+						 "PRIMARY KEY or INT PRIMARY "\
+						 "KEY");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto primary_key_exit;
 	} else {
 		sql_create_index(pParse, 0, 0, pList, 0, sortOrder, false,
@@ -1149,9 +1163,11 @@ sqlEndTable(Parse * pParse,	/* Parse context */
 
 	if (!new_space->def->opts.is_view) {
 		if (sql_space_primary_key(new_space) == NULL) {
-			sqlErrorMsg(pParse,
-					"PRIMARY KEY missing on table %s",
-					new_space->def->name);
+			const char *err_msg = tt_sprintf("PRIMARY KEY missing "\
+							 "on table %s",
+							 new_space->def->name);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			goto cleanup;
 		}
 	}
@@ -1269,8 +1285,10 @@ sql_create_view(struct Parse *parse_context, struct Token *begin,
 {
 	struct sql *db = parse_context->db;
 	if (parse_context->nVar > 0) {
-		sqlErrorMsg(parse_context,
-				"parameters are not allowed in views");
+		const char *err_msg = tt_sprintf("parameters are not allowed "\
+						 "in views");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		parse_context->is_aborted = true;
 		goto create_view_fail;
 	}
 	sqlStartTable(parse_context, name, if_exists);
@@ -1284,10 +1302,13 @@ sql_create_view(struct Parse *parse_context, struct Token *begin,
 		goto create_view_fail;
 	if (aliases != NULL) {
 		if ((int)select_res_space->def->field_count != aliases->nExpr) {
-			sqlErrorMsg(parse_context, "expected %d columns "\
-					"for '%s' but got %d", aliases->nExpr,
-					space->def->name,
-					select_res_space->def->field_count);
+			const char *err_msg =
+				tt_sprintf("expected %d columns for '%s' but "\
+					   "got %d", aliases->nExpr,
+					   space->def->name,
+					   select_res_space->def->field_count);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			parse_context->is_aborted = true;
 			goto create_view_fail;
 		}
 		sqlColumnsFromExprList(parse_context, aliases, space->def);
@@ -1609,13 +1630,17 @@ sql_drop_table(struct Parse *parse_context, struct SrcList *table_name_list,
 	 * and DROP VIEW is not used on a table.
 	 */
 	if (is_view && !space->def->opts.is_view) {
-		sqlErrorMsg(parse_context, "use DROP TABLE to delete table %s",
-				space_name);
+		const char *err_msg = tt_sprintf("use DROP TABLE to delete "\
+						 "table %s", space_name);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		parse_context->is_aborted = true;
 		goto exit_drop_table;
 	}
 	if (!is_view && space->def->opts.is_view) {
-		sqlErrorMsg(parse_context, "use DROP VIEW to delete view %s",
-				space_name);
+		const char *err_msg = tt_sprintf("use DROP VIEW to delete "\
+						 "view %s", space_name);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		parse_context->is_aborted = true;
 		goto exit_drop_table;
 	}
 	/*
@@ -1760,8 +1785,10 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child,
 		}
 	} else {
 		if (parent_space->def->opts.is_view) {
-			sqlErrorMsg(parse_context,
-					"referenced table can't be view");
+			const char *err_msg = tt_sprintf("referenced table "\
+							 "can't be view");
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			parse_context->is_aborted = true;
 			goto exit_create_fk;
 		}
 	}
@@ -2149,7 +2176,9 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	struct space_def *def = space->def;
 
 	if (def->opts.is_view) {
-		sqlErrorMsg(parse, "views can not be indexed");
+		const char *err_msg = tt_sprintf("views can not be indexed");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		parse->is_aborted = true;
 		goto exit_create_index;
 	}
 	/*
@@ -2947,11 +2976,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)
 			return;
-		}
 		sqlVdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC);
 	}
 }
@@ -3038,9 +3064,11 @@ sqlWithAdd(Parse * pParse,	/* Parsing context */
 		int i;
 		for (i = 0; i < pWith->nCte; i++) {
 			if (strcmp(zName, pWith->a[i].zName) == 0) {
-				sqlErrorMsg(pParse,
-						"duplicate WITH table name: %s",
-						zName);
+				const char *err_msg =
+					tt_sprintf("duplicate WITH table "\
+						   "name: %s", zName);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+				pParse->is_aborted = true;
 			}
 		}
 	}
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index 87d4ed4..d99a8ea 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -157,8 +157,11 @@ 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);
+			const char *err_msg = tt_sprintf("cannot modify %s "\
+							 "because it is a view",
+							 space->def->name);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			parse->is_aborted = true;
 			goto delete_from_cleanup;
 		}
 	}
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index ffcb455..14b2985 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -645,7 +645,9 @@ codeVectorCompare(Parse * pParse,	/* Code generator context */
 	int addrDone = sqlVdbeMakeLabel(v);
 
 	if (nLeft != sqlExprVectorSize(pRight)) {
-		sqlErrorMsg(pParse, "row value misused");
+		const char *err_msg = tt_sprintf("row value misused");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		return;
 	}
 	assert(pExpr->op == TK_EQ || pExpr->op == TK_NE
@@ -1757,8 +1759,10 @@ sqlExprListAppendVector(Parse * pParse,	/* Parsing context */
 	 */
 	if (pExpr->op != TK_SELECT
 	    && pColumns->nId != (n = sqlExprVectorSize(pExpr))) {
-		sqlErrorMsg(pParse, "%d columns assigned %d values",
-				pColumns->nId, n);
+		const char *err_msg = tt_sprintf("%d columns assigned %d "\
+						 "values", pColumns->nId, n);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto vector_append_error;
 	}
 
@@ -1878,7 +1882,10 @@ sqlExprListCheckLength(Parse * pParse,
 	testcase(pEList && pEList->nExpr == mx);
 	testcase(pEList && pEList->nExpr == mx + 1);
 	if (pEList && pEList->nExpr > mx) {
-		sqlErrorMsg(pParse, "too many columns in %s", zObject);
+		const char *err_msg = tt_sprintf("too many columns in %s",
+						 zObject);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 	}
 }
 
@@ -2638,19 +2645,6 @@ expr_in_type(Parse *pParse, Expr *pExpr)
 }
 
 /*
- * Load the Parse object passed as the first argument with an error
- * message of the form:
- *
- *   "sub-select returns N columns - expected M"
- */
-void
-sqlSubselectError(Parse * pParse, int nActual, int nExpect)
-{
-	const char *zFmt = "sub-select returns %d columns - expected %d";
-	sqlErrorMsg(pParse, zFmt, nActual, nExpect);
-}
-
-/*
  * Expression pExpr is a vector that has been used in a context where
  * it is not permitted. If pExpr is a sub-select vector, this routine
  * loads the Parse object with a message of the form:
@@ -2664,12 +2658,16 @@ sqlSubselectError(Parse * pParse, int nActual, int nExpect)
 void
 sqlVectorErrorMsg(Parse * pParse, Expr * pExpr)
 {
+	const char *err_msg;
 	if (pExpr->flags & EP_xIsSelect) {
-		sqlSubselectError(pParse, pExpr->x.pSelect->pEList->nExpr,
-				      1);
+		err_msg = tt_sprintf("sub-select returns %d columns - "\
+				     "expected %d",
+				     pExpr->x.pSelect->pEList->nExpr, 1);
 	} else {
-		sqlErrorMsg(pParse, "row value misused");
+		err_msg = tt_sprintf("row value misused");
 	}
+	diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+	pParse->is_aborted = true;
 }
 
 /*
@@ -2955,9 +2953,13 @@ sqlExprCheckIN(Parse * pParse, Expr * pIn)
 	int nVector = sqlExprVectorSize(pIn->pLeft);
 	if ((pIn->flags & EP_xIsSelect)) {
 		if (nVector != pIn->x.pSelect->pEList->nExpr) {
-			sqlSubselectError(pParse,
-					      pIn->x.pSelect->pEList->nExpr,
-					      nVector);
+			const char *err_msg =
+				tt_sprintf("sub-select returns %d columns - "\
+					   "expected %d",
+					   pIn->x.pSelect->pEList->nExpr,
+					   nVector);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return 1;
 		}
 	} else if (nVector != 1) {
@@ -3961,9 +3963,12 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 			AggInfo *pInfo = pExpr->pAggInfo;
 			if (pInfo == 0) {
 				assert(!ExprHasProperty(pExpr, EP_IntValue));
-				sqlErrorMsg(pParse,
-						"misuse of aggregate: %s()",
-						pExpr->u.zToken);
+				const char *err_msg =
+					tt_sprintf("misuse of aggregate: %s()",
+						   pExpr->u.zToken);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 			} else {
 				pExpr->type = pInfo->aFunc->pFunc->ret_type;
 				return pInfo->aFunc[pExpr->iAgg].iMem;
@@ -4130,7 +4135,13 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 			testcase(op == TK_SELECT);
 			if (op == TK_SELECT
 			    && (nCol = pExpr->x.pSelect->pEList->nExpr) != 1) {
-				sqlSubselectError(pParse, nCol, 1);
+				const char *err_msg =
+					tt_sprintf("sub-select returns %d "\
+						   "columns - expected %d",
+						   nCol, 1);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 			} else {
 				return sqlCodeSubselect(pParse, pExpr, 0);
 			}
@@ -4149,9 +4160,12 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 						 sqlExprVectorSize(pExpr->
 								       pLeft))
 			    ) {
-				sqlErrorMsg(pParse,
-						"%d columns assigned %d values",
-						pExpr->iTable, n);
+				const char *err_msg =
+					tt_sprintf("%d columns assigned %d "\
+						   "values", pExpr->iTable, n);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 			}
 			return pExpr->pLeft->iTable + pExpr->iColumn;
 		}
@@ -4250,7 +4264,9 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 		}
 
 	case TK_VECTOR:{
-			sqlErrorMsg(pParse, "row value misused");
+			const char *err_msg = tt_sprintf("row value misused");
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			break;
 		}
 
@@ -4350,8 +4366,11 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 		}
 	case TK_RAISE:
 		if (pParse->triggered_space == NULL) {
-			sqlErrorMsg(pParse, "RAISE() may only be used "
-					"within a trigger-program");
+			const char *err_msg = tt_sprintf("RAISE() may only be "\
+							 "used within a "\
+							 "trigger-program");
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return 0;
 		}
 		if (pExpr->on_conflict_action == ON_CONFLICT_ACTION_ABORT)
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 6f7f020..67aa675 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -322,8 +322,10 @@ sqlInsert(Parse * pParse,	/* Parser context */
 
 	/* Cannot insert into a read-only table. */
 	if (is_view && tmask == 0) {
-		sqlErrorMsg(pParse, "cannot modify %s because it is a view",
-				space_def->name);
+		const char *err_msg = tt_sprintf("cannot modify %s because it "\
+						 "is a view", space_def->name);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto insert_cleanup;
 	}
 
@@ -388,16 +390,23 @@ sqlInsert(Parse * pParse,	/* Parser context */
 				}
 			}
 			if (j >= (int) space_def->field_count) {
-				sqlErrorMsg(pParse,
-						"table %S has no column named %s",
-						pTabList, 0, pColumn->a[i].zName);
+				const char *space_name =
+					pTabList->a[0].space->def->name;
+				const char *err_msg =
+					tt_sprintf("table %s has no column "\
+						   "named %s", space_name,
+						   pColumn->a[i].zName);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+				pParse->is_aborted = true;
 				goto insert_cleanup;
 			}
 			if (bit_test(used_columns, j)) {
-				const char *err;
-				err = "table id list: duplicate column name %s";
-				sqlErrorMsg(pParse,
-						err, pColumn->a[i].zName);
+				const char *err_msg =
+					tt_sprintf("table id list: duplicate "\
+						   "column name %s",
+						   pColumn->a[i].zName);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+				pParse->is_aborted = true;
 				goto insert_cleanup;
 			}
 			bit_set(used_columns, j);
@@ -508,14 +517,21 @@ sqlInsert(Parse * pParse,	/* Parser context */
 
 	if (pColumn == NULL && nColumn != 0 &&
 	    nColumn != (int)space_def->field_count) {
-		sqlErrorMsg(pParse,
-				"table %S has %d columns but %d values were supplied",
-				pTabList, 0, space_def->field_count, nColumn);
+		const char *space_name = pTabList->a[0].space->def->name;
+		const char *err_msg =
+			tt_sprintf("table %s has %d columns but %d values "\
+				   "were supplied", space_name,
+				   space_def->field_count, nColumn);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto insert_cleanup;
 	}
 	if (pColumn != 0 && nColumn != pColumn->nId) {
-		sqlErrorMsg(pParse, "%d values for %d columns", nColumn,
-				pColumn->nId);
+		const char *err_msg =
+			tt_sprintf("%d values for %d columns", nColumn,
+				   pColumn->nId);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto insert_cleanup;
 	}
 
diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index b69f059..3653824 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -897,7 +897,9 @@ expr(A) ::= VARIABLE(X).     {
   Token t = X;
   if (pParse->parse_only) {
     spanSet(&A, &t, &t);
-    sqlErrorMsg(pParse, "bindings are not allowed in DDL");
+    const char *err_msg = tt_sprintf("bindings are not allowed in DDL");
+    diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+    pParse->is_aborted = true;
     A.pExpr = NULL;
   } else if (!(X.z[0]=='#' && sqlIsdigit(X.z[1]))) {
     u32 n = X.n;
@@ -1377,9 +1379,11 @@ trigger_cmd_list(A) ::= trigger_cmd(A) SEMI. {
 trnm(A) ::= nm(A).
 trnm(A) ::= nm DOT nm(X). {
   A = X;
-  sqlErrorMsg(pParse,
-        "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
-        "statements within triggers");
+  const char *err_msg = tt_sprintf("qualified table names are not allowed on "\
+                                   "INSERT, UPDATE, and DELETE statements "\
+                                   "within triggers");
+  diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+  pParse->is_aborted = true;
 }
 
 // Disallow the INDEX BY and NOT INDEXED clauses on UPDATE and DELETE
diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c
index 02eca37..63a1b96 100644
--- a/src/box/sql/resolve.c
+++ b/src/box/sql/resolve.c
@@ -392,14 +392,25 @@ lookupName(Parse * pParse,	/* The parsing context */
 					pOrig = pEList->a[j].pExpr;
 					if ((pNC->ncFlags & NC_AllowAgg) == 0
 					    && ExprHasProperty(pOrig, EP_Agg)) {
-						sqlErrorMsg(pParse,
-								"misuse of aliased aggregate %s",
-								zAs);
+						const char *err_msg =
+							tt_sprintf("misuse of "\
+								   "aliased "\
+								   "aggregate "\
+								   "%s", zAs);
+						diag_set(ClientError,
+							 ER_SQL_PARSER_GENERIC,
+							 err_msg);
+						pParse->is_aborted = true;
 						return WRC_Abort;
 					}
 					if (sqlExprVectorSize(pOrig) != 1) {
-						sqlErrorMsg(pParse,
-								"row value misused");
+						const char *err_msg =
+							tt_sprintf("row value "\
+								   "misused");
+						diag_set(ClientError,
+							 ER_SQL_PARSER_GENERIC,
+							 err_msg);
+						pParse->is_aborted = true;
 						return WRC_Abort;
 					}
 					resolveAlias(pParse, pEList, j, pExpr,
@@ -426,12 +437,15 @@ lookupName(Parse * pParse,	/* The parsing context */
 	 * more matches.  Either way, we have an error.
 	 */
 	if (cnt > 1) {
+		const char *err_msg;
 		if (zTab) {
-			sqlErrorMsg(pParse, "ambiguous column name: %s.%s",
-				    zTab, zCol);
+			err_msg = tt_sprintf("ambiguous column name: %s.%s",
+					     zTab, zCol);
 		} else {
-			sqlErrorMsg(pParse, "ambiguous column name: %s", zCol);
+			err_msg = tt_sprintf("ambiguous column name: %s", zCol);
 		}
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		pTopNC->nErr++;
 	}
 	if (cnt == 0) {
@@ -633,9 +647,13 @@ resolveExprStep(Walker * pWalker, Expr * pExpr)
 						    exprProbability(pList->a[1].
 								    pExpr);
 						if (pExpr->iTable < 0) {
-							sqlErrorMsg(pParse,
-									"second argument to likelihood() must be a "
-									"constant between 0.0 and 1.0");
+							const char *err_msg =
+								tt_sprintf("second argument to likelihood() must be a "\
+									   "constant between 0.0 and 1.0");
+							diag_set(ClientError,
+								 ER_SQL_PARSER_GENERIC,
+								 err_msg);
+							pParse->is_aborted = true;
 							pNC->nErr++;
 						}
 					} else {
@@ -678,9 +696,12 @@ resolveExprStep(Walker * pWalker, Expr * pExpr)
 				}
 			}
 			if (is_agg && (pNC->ncFlags & NC_AllowAgg) == 0) {
-				sqlErrorMsg(pParse,
-						"misuse of aggregate function %.*s()",
-						nId, zId);
+				const char *err_msg =
+					tt_sprintf("misuse of aggregate "\
+						   "function %.*s()", nId, zId);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 				pNC->nErr++;
 				is_agg = 0;
 			} else if (no_such_func && pParse->db->init.busy == 0
@@ -692,9 +713,13 @@ resolveExprStep(Walker * pWalker, Expr * pExpr)
 				pParse->is_aborted = true;
 				pNC->nErr++;
 			} else if (wrong_num_args) {
-				sqlErrorMsg(pParse,
-						"wrong number of arguments to function %.*s()",
-						nId, zId);
+				const char *err_msg =
+					tt_sprintf("wrong number of arguments "\
+						   "to function %.*s()", nId,
+						   zId);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 				pNC->nErr++;
 			}
 			if (is_agg)
@@ -802,7 +827,11 @@ resolveExprStep(Walker * pWalker, Expr * pExpr)
 				testcase(pExpr->op == TK_GT);
 				testcase(pExpr->op == TK_GE);
 				testcase(pExpr->op == TK_BETWEEN);
-				sqlErrorMsg(pParse, "row value misused");
+				const char *err_msg = tt_sprintf("row value "\
+								 "misused");
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 			}
 			break;
 		}
@@ -904,21 +933,6 @@ resolveOrderByTermToExprList(Parse * pParse,	/* Parsing context for error messag
 }
 
 /*
- * Generate an ORDER BY or GROUP BY term out-of-range error.
- */
-static void
-resolveOutOfRangeError(Parse * pParse,	/* The error context into which to write the error */
-		       const char *zType,	/* "ORDER" or "GROUP" */
-		       int i,	/* The index (1-based) of the term out of range */
-		       int mx	/* Largest permissible value of i */
-    )
-{
-	sqlErrorMsg(pParse,
-			"%r %s BY term out of range - should be "
-			"between 1 and %d", i, zType, mx);
-}
-
-/*
  * Analyze the ORDER BY clause in a compound SELECT statement.   Modify
  * each term of the ORDER BY clause is a constant integer between 1
  * and N where N is the number of columns in the compound SELECT.
@@ -950,7 +964,10 @@ resolveCompoundOrderBy(Parse * pParse,	/* Parsing context.  Leave error messages
 	db = pParse->db;
 #if SQL_MAX_COLUMN
 	if (pOrderBy->nExpr > db->aLimit[SQL_LIMIT_COLUMN]) {
-		sqlErrorMsg(pParse, "too many terms in ORDER BY clause");
+		const char *err_msg = tt_sprintf("too many terms in ORDER BY "\
+						 "clause");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		return 1;
 	}
 #endif
@@ -976,9 +993,13 @@ resolveCompoundOrderBy(Parse * pParse,	/* Parsing context.  Leave error messages
 			pE = sqlExprSkipCollate(pItem->pExpr);
 			if (sqlExprIsInteger(pE, &iCol)) {
 				if (iCol <= 0 || iCol > pEList->nExpr) {
-					resolveOutOfRangeError(pParse, "ORDER",
-							       i + 1,
-							       pEList->nExpr);
+					const char *err_msg =
+						tt_sprintf("ORDER BY term out "\
+							   "of range - should "\
+							   "be between 1 and "\
+							   "%d", pEList->nExpr);
+					diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+					pParse->is_aborted = true;
 					return 1;
 				}
 			} else {
@@ -1024,9 +1045,11 @@ resolveCompoundOrderBy(Parse * pParse,	/* Parsing context.  Leave error messages
 	}
 	for (i = 0; i < pOrderBy->nExpr; i++) {
 		if (pOrderBy->a[i].done == 0) {
-			sqlErrorMsg(pParse,
-					"%r ORDER BY term does not match any "
-					"column in the result set", i + 1);
+			const char *err_msg =
+				tt_sprintf("ORDER BY term does not match any "\
+					   "column in the result set");
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return 1;
 		}
 	}
@@ -1059,8 +1082,10 @@ sqlResolveOrderGroupBy(Parse * pParse,	/* Parsing context.  Leave error messages
 		return 0;
 #if SQL_MAX_COLUMN
 	if (pOrderBy->nExpr > db->aLimit[SQL_LIMIT_COLUMN]) {
-		sqlErrorMsg(pParse, "too many terms in %s BY clause",
-				zType);
+		const char *err_msg = tt_sprintf("too many terms in %s BY "\
+						 "clause", zType);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		return 1;
 	}
 #endif
@@ -1069,8 +1094,12 @@ sqlResolveOrderGroupBy(Parse * pParse,	/* Parsing context.  Leave error messages
 	for (i = 0, pItem = pOrderBy->a; i < pOrderBy->nExpr; i++, pItem++) {
 		if (pItem->u.x.iOrderByCol) {
 			if (pItem->u.x.iOrderByCol > pEList->nExpr) {
-				resolveOutOfRangeError(pParse, zType, i + 1,
-						       pEList->nExpr);
+				const char *err_msg =
+					tt_sprintf("%s BY term out of range - "\
+						   "should be between 1 and %d",
+						   zType, pEList->nExpr);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+				pParse->is_aborted = true;
 				return 1;
 			}
 			resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol - 1,
@@ -1136,8 +1165,12 @@ resolveOrderGroupBy(NameContext * pNC,	/* The name context of the SELECT stateme
 			 * order-by term to a copy of the result-set expression
 			 */
 			if (iCol < 1 || iCol > 0xffff) {
-				resolveOutOfRangeError(pParse, zType, i + 1,
-						       nResult);
+				const char *err_msg =
+					tt_sprintf("%s BY term out of range - "\
+						   "should be between 1 and %d",
+						   zType, nResult);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+				pParse->is_aborted = true;
 				return 1;
 			}
 			pItem->u.x.iOrderByCol = (u16) iCol;
@@ -1417,9 +1450,15 @@ resolveSelectStep(Walker * pWalker, Select * p)
 			for (i = 0, pItem = pGroupBy->a; i < pGroupBy->nExpr;
 			     i++, pItem++) {
 				if (ExprHasProperty(pItem->pExpr, EP_Agg)) {
-					sqlErrorMsg(pParse,
-							"aggregate functions are not allowed in "
-							"the GROUP BY clause");
+					const char *err_msg =
+						tt_sprintf("aggregate "\
+							   "functions are not "\
+							   "allowed in the "\
+							   "GROUP BY clause");
+					diag_set(ClientError,
+						 ER_SQL_PARSER_GENERIC,
+						 err_msg);
+					pParse->is_aborted = true;
 					return WRC_Abort;
 				}
 			}
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index 261a8bd..f15e453 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -397,13 +397,18 @@ sqlJoinType(Parse * pParse, Token * pA, Token * pB, Token * pC)
 	}
 	if ((jointype & (JT_INNER | JT_OUTER)) == (JT_INNER | JT_OUTER) ||
 	    (jointype & JT_ERROR) != 0) {
-		const char *zSp = " ";
-		assert(pB != 0);
+		const char *err_msg;
 		if (pC == 0) {
-			zSp++;
+			err_msg = tt_sprintf("unknown or unsupported join "\
+					     "type: %.*s %.*s", pA->n, pA->z,
+					     pB->n, pB->z);
+		} else {
+			err_msg = tt_sprintf("unknown or unsupported join "\
+					     "type: %.*s %.*s %.*s", pA->n,
+					     pA->z, pB->n, pB->z, pC->n, pC->z);
 		}
-		sqlErrorMsg(pParse, "unknown or unsupported join type: "
-				"%T %T%s%T", pA, pB, zSp, pC);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		jointype = JT_INNER;
 	} else if ((jointype & JT_OUTER) != 0
 		   && (jointype & (JT_LEFT | JT_RIGHT)) != JT_LEFT) {
@@ -590,9 +595,13 @@ sqlProcessJoin(Parse * pParse, Select * p)
 		 */
 		if (pRight->fg.jointype & JT_NATURAL) {
 			if (pRight->pOn || pRight->pUsing) {
-				sqlErrorMsg(pParse,
-						"a NATURAL join may not have "
-						"an ON or USING clause", 0);
+				const char *err_msg =
+					tt_sprintf("a NATURAL join may not "\
+						   "have an ON or USING "\
+						   "clause");
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 				return 1;
 			}
 			for (j = 0; j < (int)right_space->def->field_count; j++) {
@@ -613,8 +622,11 @@ sqlProcessJoin(Parse * pParse, Select * p)
 		/* Disallow both ON and USING clauses in the same join
 		 */
 		if (pRight->pOn && pRight->pUsing) {
-			sqlErrorMsg(pParse, "cannot have both ON and USING "
-					"clauses in the same join");
+			const char *err_msg =
+				tt_sprintf("cannot have both ON and USING "
+					   "clauses in the same join");
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return 1;
 		}
 
@@ -650,10 +662,16 @@ sqlProcessJoin(Parse * pParse, Select * p)
 				    || !tableAndColumnIndex(pSrc, i + 1, zName,
 							    &iLeft, &iLeftCol)
 				    ) {
-					sqlErrorMsg(pParse,
-							"cannot join using column %s - column "
-							"not present in both tables",
-							zName);
+					const char *err_msg =
+						tt_sprintf("cannot join using "\
+							   "column %s - "\
+							   "column not "\
+							   "present in both "\
+							   "tables", zName);
+					diag_set(ClientError,
+						 ER_SQL_PARSER_GENERIC,
+						 err_msg);
+					pParse->is_aborted = true;
 					return 1;
 				}
 				addWhereTerm(pParse, pSrc, iLeft, iLeftCol,
@@ -2601,16 +2619,20 @@ multiSelect(Parse * pParse,	/* Parsing context */
 	pPrior = p->pPrior;
 	dest = *pDest;
 	if (pPrior->pOrderBy) {
-		sqlErrorMsg(pParse,
-				"ORDER BY clause should come after %s not before",
-				selectOpName(p->op));
+		const char *err_msg =
+			tt_sprintf("ORDER BY clause should come after %s not "\
+				   "before", selectOpName(p->op));
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		rc = 1;
 		goto multi_select_end;
 	}
 	if (pPrior->pLimit) {
-		sqlErrorMsg(pParse,
-				"LIMIT clause should come after %s not before",
-				selectOpName(p->op));
+		const char *err_msg =
+			tt_sprintf("LIMIT clause should come after %s not "\
+				   "before", selectOpName(p->op));
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		rc = 1;
 		goto multi_select_end;
 	}
@@ -2991,14 +3013,17 @@ multiSelect(Parse * pParse,	/* Parsing context */
 void
 sqlSelectWrongNumTermsError(struct Parse *parse, struct Select * p)
 {
+	const char *err_msg;
 	if (p->selFlags & SF_Values) {
-		sqlErrorMsg(parse, "all VALUES must have the same number "\
-				"of terms");
+		err_msg = tt_sprintf("all VALUES must have the same number of "\
+				     "terms");
 	} else {
-		sqlErrorMsg(parse, "SELECTs to the left and right of %s "
-				"do not have the same number of result columns",
-				selectOpName(p->op));
+		err_msg = tt_sprintf("SELECTs to the left and right of %s do "\
+				     "not have the same number of result "\
+				     "columns", selectOpName(p->op));
 	}
+	diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+	parse->is_aborted = true;
 }
 
 /**
@@ -4521,21 +4546,6 @@ convertCompoundSelectToSubquery(Walker * pWalker, Select * p)
 	return WRC_Continue;
 }
 
-/*
- * Check to see if the FROM clause term pFrom has table-valued function
- * arguments.  If it does, leave an error message in pParse and return
- * non-zero, since pFrom is not allowed to be a table-valued function.
- */
-static int
-cannotBeFunction(Parse * pParse, struct SrcList_item *pFrom)
-{
-	if (pFrom->fg.isTabFunc) {
-		sqlErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
-		return 1;
-	}
-	return 0;
-}
-
 #ifndef SQL_OMIT_CTE
 /*
  * Argument pWith (which may be NULL) points to a linked list of nested
@@ -4630,11 +4640,20 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom)
 		 * In this case, proceed.
 		 */
 		if (pCte->zCteErr) {
-			sqlErrorMsg(pParse, pCte->zCteErr, pCte->zName);
+			const char *err_msg =
+				tt_sprintf(pCte->zCteErr, pCte->zName);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return SQL_ERROR;
 		}
-		if (cannotBeFunction(pParse, pFrom))
+		if (pFrom->fg.isTabFunc) {
+			const char *err_msg =
+				tt_sprintf("'%s' is not a function",
+					   pFrom->zName);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return SQL_ERROR;
+		}
 
 		assert(pFrom->space == NULL);
 		pFrom->space = sql_ephemeral_space_new(pParse, pCte->zName);
@@ -4666,9 +4685,11 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom)
 			}
 		}
 		if (ref_counter > 1) {
-			sqlErrorMsg(pParse,
-					"multiple references to recursive table: %s",
-					pCte->zName);
+			const char *err_msg =
+				tt_sprintf("multiple references to recursive "\
+					   "table: %s", pCte->zName);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return SQL_ERROR;
 		}
 		assert(ref_counter == 0 ||
@@ -4684,10 +4705,14 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom)
 		pEList = pLeft->pEList;
 		if (pCte->pCols) {
 			if (pEList && pEList->nExpr != pCte->pCols->nExpr) {
-				sqlErrorMsg(pParse,
-						"table %s has %d values for %d columns",
-						pCte->zName, pEList->nExpr,
-						pCte->pCols->nExpr);
+				const char *err_msg =
+					tt_sprintf("table %s has %d values "\
+						   "for %d columns",
+						   pCte->zName, pEList->nExpr,
+						   pCte->pCols->nExpr);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 				pParse->pWith = pSavedWith;
 				return SQL_ERROR;
 			}
@@ -4843,8 +4868,15 @@ selectExpander(Walker * pWalker, Select * p)
 			struct space *space = sql_lookup_space(pParse, pFrom);
 			if (space == NULL)
 				return WRC_Abort;
-			if (cannotBeFunction(pParse, pFrom))
+			if (pFrom->fg.isTabFunc) {
+				const char *err_msg =
+					tt_sprintf("'%s' is not a function",
+						   pFrom->zName);
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+					 err_msg);
+				pParse->is_aborted = true;
 				return WRC_Abort;
+			}
 			if (space->def->opts.is_view) {
 				struct Select *select =
 					sql_view_compile(db, space->def->opts.sql);
@@ -5254,9 +5286,11 @@ resetAccumulator(Parse * pParse, AggInfo * pAggInfo)
 			Expr *pE = pFunc->pExpr;
 			assert(!ExprHasProperty(pE, EP_xIsSelect));
 			if (pE->x.pList == 0 || pE->x.pList->nExpr != 1) {
-				sqlErrorMsg(pParse,
-						"DISTINCT aggregates must have exactly one "
-						"argument");
+				const char *err_msg =
+					tt_sprintf("DISTINCT aggregates must "\
+						   "have exactly one argument");
+				diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+				pParse->is_aborted = true;
 				pFunc->iDistinct = -1;
 			} else {
 				struct sql_key_info *key_info =
@@ -5526,10 +5560,13 @@ sqlSelect(Parse * pParse,		/* The parser context */
 		 * columns in the SELECT on the RHS
 		 */
 		if ((int)space->def->field_count != pSub->pEList->nExpr) {
-			sqlErrorMsg(pParse,
-					"expected %d columns for '%s' but got %d",
-					space->def->field_count, space->def->name,
-					pSub->pEList->nExpr);
+			const char *err_msg =
+				tt_sprintf("expected %d columns for '%s' but "\
+					   "got %d", space->def->field_count,
+					   space->def->name,
+					   pSub->pEList->nExpr);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			goto select_end;
 		}
 
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 85718e1..5a74c65 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -3182,7 +3182,6 @@ void sqlTreeViewWith(TreeView *, const With *);
 #endif
 
 void sqlSetString(char **, sql *, const char *);
-void sqlErrorMsg(Parse *, const char *, ...);
 void sqlDequote(char *);
 void sqlNormalizeName(char *z);
 void sqlTokenInit(Token *, char *);
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 2f1268a..297ba01 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -621,8 +621,11 @@ codeTriggerProgram(Parse * pParse,	/* The parser context */
 	sqlSubProgramsRemaining--;
 
 	if (sqlSubProgramsRemaining == 0) {
-		sqlErrorMsg(pParse,
-				"Maximum number of chained trigger activations exceeded.");
+		const char *err_msg = tt_sprintf("Maximum number of chained "\
+						 "trigger activations "\
+						 "exceeded.");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 	}
 
 	for (pStep = pStepList; pStep; pStep = pStep->pNext) {
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 05ceeb4..88ebc90 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -139,8 +139,10 @@ 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);
+		const char *err_msg = tt_sprintf("cannot modify %s because it "\
+						 "is a view", space->def->name);
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		goto update_cleanup;
 	}
 
@@ -178,10 +180,15 @@ sqlUpdate(Parse * pParse,		/* The parser context */
 				    sql_space_column_is_in_pk(space, j))
 					is_pk_modified = true;
 				if (aXRef[j] != -1) {
-					sqlErrorMsg(pParse,
-							"set id list: duplicate"
-							" column name %s",
-							pChanges->a[i].zName);
+					const char *err_msg =
+						tt_sprintf("set id list: "\
+							   "duplicate column "\
+							   "name %s",
+							   pChanges->a[i].zName);
+					diag_set(ClientError,
+						 ER_SQL_PARSER_GENERIC,
+						 err_msg);
+					pParse->is_aborted = true;
 					goto update_cleanup;
 				}
 				aXRef[j] = i;
diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index 07527ff..cac404f 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -211,37 +211,6 @@ sqlErrorWithMsg(sql * db, int err_code, const char *zFormat, ...)
 }
 
 /*
- * Add an error message to diag.
- * The following formatting characters are allowed:
- *
- *      %s      Insert a string
- *      %z      A string that should be freed after use
- *      %d      Insert an integer
- *      %T      Insert a token
- *      %S      Insert the first element of a SrcList
- *
- * This function should be used to report any error that occurs while
- * compiling an SQL statement (i.e. within sql_prepare()). The
- * last thing the sql_prepare() function does is copy the error
- * stored by this function into the database handle using sqlError().
- * Functions sqlError() or sqlErrorWithMsg() should be used
- * during statement execution (sql_step() etc.).
- */
-void
-sqlErrorMsg(Parse * pParse, const char *zFormat, ...)
-{
-	char *zMsg;
-	va_list ap;
-	sql *db = pParse->db;
-	va_start(ap, zFormat);
-	zMsg = sqlVMPrintf(db, zFormat, ap);
-	va_end(ap);
-	diag_set(ClientError, ER_SQL_PARSER_GENERIC, zMsg);
-	sqlDbFree(db, zMsg);
-	pParse->is_aborted = true;
-}
-
-/*
  * Convert an SQL-style quoted string into a normal string by removing
  * the quote characters.  The conversion is done in-place.  If the
  * input does not begin with a quote character, then this routine
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 9957f3a..d4fbf17 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -1222,7 +1222,9 @@ valueFromFunction(sql * db,	/* The database connection */
 	pFunc->xSFunc(&ctx, nVal, apVal);
 	if (ctx.isError) {
 		rc = ctx.isError;
-		sqlErrorMsg(pCtx->pParse, "%s", sql_value_text(pVal));
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC,
+			 sql_value_text(pVal));
+		pCtx->pParse->is_aborted = true;
 	} else {
 		sql_value_apply_type(pVal, type);
 		assert(rc == SQL_OK);
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index 33885d0..e2c91e0 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -3914,7 +3914,9 @@ wherePathSolver(WhereInfo * pWInfo, LogEst nRowEst)
 	}
 
 	if (nFrom == 0) {
-		sqlErrorMsg(pParse, "no query solution");
+		const char *err_msg = tt_sprintf("no query solution");
+		diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+		pParse->is_aborted = true;
 		sqlDbFree(db, pSpace);
 		return SQL_ERROR;
 	}
diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c
index 6df28ad..535914f 100644
--- a/src/box/sql/whereexpr.c
+++ b/src/box/sql/whereexpr.c
@@ -1497,9 +1497,11 @@ sqlWhereTabFuncArgs(Parse * pParse,	/* Parsing context */
 		while (k < (int)space_def->field_count)
 			k++;
 		if (k >= (int)space_def->field_count) {
-			sqlErrorMsg(pParse,
-					"too many arguments on %s() - max %d",
-					space_def->name, j);
+			const char *err_msg =
+				tt_sprintf("too many arguments on %s() - max "\
+					   "%d", space_def->name, j);
+			diag_set(ClientError, ER_SQL_PARSER_GENERIC, err_msg);
+			pParse->is_aborted = true;
 			return;
 		}
 		pColRef = sqlExprAlloc(pParse->db, TK_COLUMN, 0, 0);
diff --git a/test/sql-tap/e_select1.test.lua b/test/sql-tap/e_select1.test.lua
index e190ad7..16a31a8 100755
--- a/test/sql-tap/e_select1.test.lua
+++ b/test/sql-tap/e_select1.test.lua
@@ -1855,13 +1855,13 @@ test:do_catchsql_test(
     "e_select-8.7.1.1",
     "SELECT x FROM d1 UNION ALL SELECT a FROM d2 ORDER BY x*z",
     {
-        1, "1st ORDER BY term does not match any column in the result set"})
+        1, "ORDER BY term does not match any column in the result set"})
 
 test:do_catchsql_test(
     "e_select-8.7.1.2",
     "SELECT x,z FROM d1 UNION ALL SELECT a,b FROM d2 ORDER BY x, x/z",
     {
-        1, "2nd ORDER BY term does not match any column in the result set"})
+        1, "ORDER BY term does not match any column in the result set"})
 
 test:do_select_tests(
     "e_select-8.7.2",
@@ -2077,20 +2077,20 @@ test:do_select_tests(
 -- EVIDENCE-OF: R-39265-04070 If no matching expression can be found in
 -- the result columns of any constituent SELECT, it is an error.
 --
-for _, val in ipairs({{1, "SELECT a FROM d5 UNION SELECT c FROM d6 ORDER BY a+1", "1st"},
-    {2, "SELECT a FROM d5 UNION SELECT c FROM d6 ORDER BY a, a+1", "2nd"},
-    {3, "SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY \"hello\"", "1st"},
-    {4, "SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY blah", "1st"},
-    {5, "SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY c,d,c+d", "3rd"},
-    {6, "SELECT * FROM d5 EXCEPT SELECT * FROM d7 ORDER BY 1,2,b,a/b", "4th"}}) do
+for _, val in ipairs({{1, "SELECT a FROM d5 UNION SELECT c FROM d6 ORDER BY a+1"},
+    {2, "SELECT a FROM d5 UNION SELECT c FROM d6 ORDER BY a, a+1"},
+    {3, "SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY \"hello\""},
+    {4, "SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY blah"},
+    {5, "SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY c,d,c+d"},
+    {6, "SELECT * FROM d5 EXCEPT SELECT * FROM d7 ORDER BY 1,2,b,a/b"}}) do
     local tn = val[1]
     local select = val[2]
-    local err_param = val[3]
     test:do_catchsql_test(
         "e_select-8.14."..tn,
         select,
         {
-            1, string.format("%s ORDER BY term does not match any column in the result set", err_param)})
+            1, "ORDER BY term does not match any column in the result set"
+        })
 end
 -- EVIDENCE-OF: R-03407-11483 Each term of the ORDER BY clause is
 -- processed separately and may be matched against result columns from
diff --git a/test/sql-tap/null.test.lua b/test/sql-tap/null.test.lua
index 50a2cfb..cf6bcc9 100755
--- a/test/sql-tap/null.test.lua
+++ b/test/sql-tap/null.test.lua
@@ -295,7 +295,7 @@ test:do_catchsql_test(
         select b from t1 union select c from t1 order by t1.a;
     ]], {
         -- <null-6.5>
-        1, "1st ORDER BY term does not match any column in the result set"
+        1, "ORDER BY term does not match any column in the result set"
         -- </null-6.5>
     })
 
@@ -305,7 +305,7 @@ test:do_catchsql_test(
         select b from t1 union select c from t1 order by t1.a;
     ]], {
         -- <null-6.6>
-        1, "1st ORDER BY term does not match any column in the result set"
+        1, "ORDER BY term does not match any column in the result set"
         -- </null-6.6>
     })
 
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index d73429a..470a8f7 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -840,7 +840,7 @@ test:do_catchsql_test(
         SELECT * FROM t5 ORDER BY 3;
     ]], {
         -- <select1-4.10.1>
-        1, "1st ORDER BY term out of range - should be between 1 and 2"
+        1, "ORDER BY term out of range - should be between 1 and 2"
         -- </select1-4.10.1>
     })
 
@@ -850,7 +850,7 @@ test:do_catchsql_test(
         SELECT * FROM t5 ORDER BY -1;
     ]], {
         -- <select1-4.10.2>
-        1, "1st ORDER BY term out of range - should be between 1 and 2"
+        1, "ORDER BY term out of range - should be between 1 and 2"
         -- </select1-4.10.2>
     })
 
@@ -1334,7 +1334,7 @@ test:do_catchsql2_test(
             ORDER BY f2+101;
         ]], {
             -- <select1-6.11>
-            1, "1st ORDER BY term does not match any column in the result set"
+            1, "ORDER BY term does not match any column in the result set"
             -- </select1-6.11>
         })
 
diff --git a/test/sql-tap/select3.test.lua b/test/sql-tap/select3.test.lua
index 9fb825f..d2807bf 100755
--- a/test/sql-tap/select3.test.lua
+++ b/test/sql-tap/select3.test.lua
@@ -157,7 +157,7 @@ test:do_catchsql_test("select3-2.10", [[
   SELECT log, count(*) FROM t1 GROUP BY 0 ORDER BY log;
 ]], {
   -- <select3-2.10>
-  1, "1st GROUP BY term out of range - should be between 1 and 2"
+  1, "GROUP BY term out of range - should be between 1 and 2"
   -- </select3-2.10>
 })
 
@@ -165,7 +165,7 @@ test:do_catchsql_test("select3-2.11", [[
   SELECT log, count(*) FROM t1 GROUP BY 3 ORDER BY log;
 ]], {
   -- <select3-2.11>
-  1, "1st GROUP BY term out of range - should be between 1 and 2"
+  1, "GROUP BY term out of range - should be between 1 and 2"
   -- </select3-2.11>
 })
 
diff --git a/test/sql-tap/select4.test.lua b/test/sql-tap/select4.test.lua
index bd2ada9..e451038 100755
--- a/test/sql-tap/select4.test.lua
+++ b/test/sql-tap/select4.test.lua
@@ -450,7 +450,7 @@ test:do_catchsql_test(
         ORDER BY "xyzzy";
     ]], {
         -- <select4-5.2c>
-        1, "1st ORDER BY term does not match any column in the result set"
+        1, "ORDER BY term does not match any column in the result set"
         -- </select4-5.2c>
     })
 
@@ -463,7 +463,7 @@ test:do_catchsql_test(
         ORDER BY "xyzzy";
     ]], {
         -- <select4-5.2d>
-        1, "1st ORDER BY term does not match any column in the result set"
+        1, "ORDER BY term does not match any column in the result set"
         -- </select4-5.2d>
     })
 
@@ -515,7 +515,7 @@ test:do_catchsql_test(
         ORDER BY 2;
     ]], {
         -- <select4-5.2h>
-        1, "1st ORDER BY term out of range - should be between 1 and 1"
+        1, "ORDER BY term out of range - should be between 1 and 1"
         -- </select4-5.2h>
     })
 
diff --git a/test/sql-tap/tkt2822.test.lua b/test/sql-tap/tkt2822.test.lua
index 4212cbd..d125008 100755
--- a/test/sql-tap/tkt2822.test.lua
+++ b/test/sql-tap/tkt2822.test.lua
@@ -200,7 +200,7 @@ test:do_catchsql_test(
         SELECT a, b, c FROM t1 UNION ALL SELECT a, b, c FROM t2 ORDER BY x
     ]], {
         -- <tkt2822-4.1>
-        1, "1st ORDER BY term does not match any column in the result set"
+        1, "ORDER BY term does not match any column in the result set"
         -- </tkt2822-4.1>
     })
 
@@ -298,7 +298,7 @@ test:do_test(
         ]]
     end, {
         -- <tkt2822-7.1>
-        1, "1st ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.1>
     })
 
@@ -308,7 +308,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 0;
     ]], {
         -- <tkt2822-7.2.1>
-        1, "2nd ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.2.1>
     })
 
@@ -318,7 +318,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 26;
     ]], {
         -- <tkt2822-7.2.2>
-        1, "2nd ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.2.2>
     })
 
@@ -328,7 +328,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 65536;
     ]], {
         -- <tkt2822-7.2.3>
-        1, "2nd ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.2.3>
     })
 
@@ -338,7 +338,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 0;
     ]], {
         -- <tkt2822-7.3>
-        1, "3rd ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.3>
     })
 
@@ -348,7 +348,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 3, 0;
     ]], {
         -- <tkt2822-7.4>
-        1, "4th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.4>
     })
 
@@ -358,7 +358,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 3, 4, 5, 6, 7, 8, 0;
     ]], {
         -- <tkt2822-7.9>
-        1, "9th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.9>
     })
 
@@ -368,7 +368,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 0;
     ]], {
         -- <tkt2822-7.10>
-        1, "10th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.10>
     })
 
@@ -378,7 +378,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0;
     ]], {
         -- <tkt2822-7.11>
-        1, "11th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.11>
     })
 
@@ -388,7 +388,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0;
     ]], {
         -- <tkt2822-7.12>
-        1, "12th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.12>
     })
 
@@ -398,7 +398,7 @@ test:do_catchsql_test(
         SELECT * FROM t7 ORDER BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 0;
     ]], {
         -- <tkt2822-7.13>
-        1, "13th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.13>
     })
 
@@ -409,7 +409,7 @@ test:do_catchsql_test(
                                  11,12,13,14,15,16,17,18,19, 0
     ]], {
         -- <tkt2822-7.20>
-        1, "20th ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.20>
     })
 
@@ -420,7 +420,7 @@ test:do_catchsql_test(
                                  11,12,13,14,15,16,17,18,19, 20, 0
     ]], {
         -- <tkt2822-7.21>
-        1, "21st ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.21>
     })
 
@@ -431,7 +431,7 @@ test:do_catchsql_test(
                                  11,12,13,14,15,16,17,18,19, 20, 21, 0
     ]], {
         -- <tkt2822-7.22>
-        1, "22nd ORDER BY term out of range - should be between 1 and 25"
+        1, "ORDER BY term out of range - should be between 1 and 25"
         -- </tkt2822-7.22>
     })
 
diff --git a/test/sql-tap/with1.test.lua b/test/sql-tap/with1.test.lua
index 16c9b12..deb4cbb 100755
--- a/test/sql-tap/with1.test.lua
+++ b/test/sql-tap/with1.test.lua
@@ -782,7 +782,7 @@ test:do_catchsql_test("10.7.1", [[
   SELECT * FROM t
 ]], {
   -- <10.7.1>
-  1, "1st ORDER BY term does not match any column in the result set"
+  1, "ORDER BY term does not match any column in the result set"
   -- </10.7.1>
 })
 
-- 
2.7.4





More information about the Tarantool-patches mailing list