[tarantool-patches] [PATCH v4 1/6] sql: refactor sql_expr_compile to return AST

Kirill Shcherbatov kshcherbatov at tarantool.org
Wed Jun 20 13:46:11 MSK 2018


---
 src/box/alter.cc        | 12 +++++++-----
 src/box/sql.c           | 10 ++++++----
 src/box/sql.h           |  9 ++++-----
 src/box/sql/prepare.c   | 10 ++++++++++
 src/box/sql/sqliteInt.h |  3 ++-
 src/box/sql/tokenize.c  | 40 ++++++++++++++++++++++++++--------------
 6 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index 5784e27..706eab4 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -405,11 +405,13 @@ field_def_decode(struct field_def *field, const char **data,
 				     "string, scalar and any fields"));
 	}
 
-	if (field->default_value != NULL &&
-	    sql_expr_compile(sql_get(), field->default_value,
-			     strlen(field->default_value),
-			     &field->default_value_expr) != 0)
-		diag_raise();
+	const char *dv = field->default_value;
+	if (dv != NULL) {
+		field->default_value_expr = sql_expr_compile(sql_get(), dv,
+							     strlen(dv));
+		if (field->default_value_expr == NULL)
+			diag_raise();
+	}
 }
 
 /**
diff --git a/src/box/sql.c b/src/box/sql.c
index 82f3d6d..0ae33b6 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -1815,10 +1815,12 @@ sql_check_list_item_init(struct ExprList *expr_list, int column,
 			return -1;
 		}
 	}
-	if (expr_str != NULL && sql_expr_compile(db, expr_str, expr_str_len,
-						 &item->pExpr) != 0) {
-		sqlite3DbFree(db, item->zName);
-		return -1;
+	if (expr_str != NULL) {
+		item->pExpr = sql_expr_compile(db, expr_str, expr_str_len);
+		if (item->pExpr == NULL) {
+			sqlite3DbFree(db, item->zName);
+			return -1;
+		}
 	}
 	return 0;
 }
diff --git a/src/box/sql.h b/src/box/sql.h
index 834f951..ef9e099 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -75,13 +75,12 @@ struct Table;
  * @param db SQL context handle.
  * @param expr Expression to parse.
  * @param expr_len Length of @an expr.
- * @param[out] result Result: AST structure.
  *
- * @retval Error code if any.
+ * @retval NULL on error.
+ * @retval not NULL Expr AST pointer on success.
  */
-int
-sql_expr_compile(struct sqlite3 *db, const char *expr, int expr_len,
-		 struct Expr **result);
+struct Expr *
+sql_expr_compile(struct sqlite3 *db, const char *expr, int expr_len);
 
 /**
  * This routine executes parser on 'CREATE VIEW ...' statement
diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index e43fbcb..bddc21a 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -454,5 +454,15 @@ sql_parser_destroy(Parse *parser)
 	}
 	parser->disableLookaside = 0;
 	sqlite3DbFree(db, parser->zErrMsg);
+	switch (parser->parsed_ast_type) {
+	case AST_TYPE_SELECT:
+		sql_select_delete(db, parser->parsed_ast.select);
+		break;
+	case AST_TYPE_EXPR:
+		sql_expr_delete(db, parser->parsed_ast.expr, false);
+		break;
+	default:
+		assert(parser->parsed_ast_type == AST_TYPE_UNDEFINED);
+	}
 	region_destroy(&parser->region);
 }
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index 47360fa..88644c6 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -2852,7 +2852,8 @@ struct TriggerPrg {
 };
 
 enum ast_type {
-	AST_TYPE_SELECT = 0,
+	AST_TYPE_UNDEFINED = 0,
+	AST_TYPE_SELECT,
 	AST_TYPE_EXPR,
 	ast_type_MAX
 };
diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c
index 3fdf14d..5654e63 100644
--- a/src/box/sql/tokenize.c
+++ b/src/box/sql/tokenize.c
@@ -42,6 +42,7 @@
 
 #include "say.h"
 #include "sqliteInt.h"
+#include "tarantoolInt.h"
 
 /* Character classes for tokenizing
  *
@@ -510,8 +511,13 @@ sqlite3RunParser(Parse * pParse, const char *zSql, char **pzErrMsg)
 	}
 	if (pParse->rc != SQLITE_OK && pParse->rc != SQLITE_DONE
 	    && pParse->zErrMsg == 0) {
-		pParse->zErrMsg =
-		    sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
+		const char *error;
+		if (is_tarantool_error(pParse->rc) &&
+		    tarantoolErrorMessage() != NULL)
+			error = tarantoolErrorMessage();
+		else
+			error = sqlite3ErrStr(pParse->rc);
+		pParse->zErrMsg = sqlite3MPrintf(db, "%s", error);
 	}
 	assert(pzErrMsg != 0);
 	if (pParse->zErrMsg) {
@@ -539,9 +545,8 @@ sqlite3RunParser(Parse * pParse, const char *zSql, char **pzErrMsg)
 	return nErr;
 }
 
-int
-sql_expr_compile(sqlite3 *db, const char *expr, int expr_len,
-		 struct Expr **result)
+struct Expr *
+sql_expr_compile(sqlite3 *db, const char *expr, int expr_len)
 {
 	const char *outer = "SELECT ";
 	int len = strlen(outer) + expr_len;
@@ -550,22 +555,25 @@ sql_expr_compile(sqlite3 *db, const char *expr, int expr_len,
 	sql_parser_create(&parser, db);
 	parser.parse_only = true;
 
+	struct Expr *expression = NULL;
 	char *stmt = (char *)region_alloc(&parser.region, len + 1);
 	if (stmt == NULL) {
 		diag_set(OutOfMemory, len + 1, "region_alloc", "stmt");
-		return -1;
+		goto end;
 	}
 	sprintf(stmt, "%s%.*s", outer, expr_len, expr);
 
 	char *unused;
 	if (sqlite3RunParser(&parser, stmt, &unused) != SQLITE_OK ||
 	    parser.parsed_ast_type != AST_TYPE_EXPR) {
-		diag_set(ClientError, ER_SQL_EXECUTE, expr);
-		return -1;
+		diag_set(ClientError, ER_SQL_EXECUTE, stmt);
+	} else {
+		expression = parser.parsed_ast.expr;
+		parser.parsed_ast.expr = NULL;
 	}
-	*result = parser.parsed_ast.expr;
+end:
 	sql_parser_destroy(&parser);
-	return 0;
+	return expression;
 }
 
 struct Select *
@@ -574,14 +582,18 @@ sql_view_compile(struct sqlite3 *db, const char *view_stmt)
 	struct Parse parser;
 	sql_parser_create(&parser, db);
 	parser.parse_only = true;
+
+	struct Select *select = NULL;
+
 	char *unused;
 	if (sqlite3RunParser(&parser, view_stmt, &unused) != SQLITE_OK ||
 	    parser.parsed_ast_type != AST_TYPE_SELECT) {
 		diag_set(ClientError, ER_SQL_EXECUTE, view_stmt);
-		sql_parser_destroy(&parser);
-		return NULL;
+	} else {
+		select = parser.parsed_ast.select;
+		parser.parsed_ast.select = NULL;
 	}
-	struct Select *result = parser.parsed_ast.select;
+
 	sql_parser_destroy(&parser);
-	return result;
+	return select;
 }
-- 
2.7.4





More information about the Tarantool-patches mailing list