[tarantool-patches] [PATCH v1 2/4] sql: patch sql_trigger_step_allocate to use Parser

Kirill Shcherbatov kshcherbatov at tarantool.org
Fri Feb 15 16:30:49 MSK 2019


The code was refactored so that the sql_trigger_step_allocate
function would use the parser object instead of database
connection. Also performed some additional names refactoring in
adjacent places.

Needed for #3931
---
 src/box/sql/parse.y   |   8 +-
 src/box/sql/sqlInt.h  |  69 ++++++++++++++--
 src/box/sql/trigger.c | 185 +++++++++++++++++-------------------------
 3 files changed, 140 insertions(+), 122 deletions(-)

diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index 4713d0d09..1a18d5f89 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -1397,19 +1397,19 @@ tridxby ::= NOT INDEXED. {
 // UPDATE 
 trigger_cmd(A) ::=
    UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z).  
-   {A = sqlTriggerUpdateStep(pParse->db, &X, Y, Z, R);}
+   {A = sql_trigger_update_step(pParse, &X, Y, Z, R);}
 
 // INSERT
 trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) idlist_opt(F) select(S).
-   {A = sqlTriggerInsertStep(pParse->db, &X, F, S, R);/*A-overwrites-R*/}
+   {A = sql_trigger_insert_step(pParse, &X, F, S, R);/*A-overwrites-R*/}
 
 // DELETE
 trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
-   {A = sqlTriggerDeleteStep(pParse->db, &X, Y);}
+   {A = sql_trigger_delete_step(pParse, &X, Y);}
 
 // SELECT
 trigger_cmd(A) ::= select(X).
-   {A = sqlTriggerSelectStep(pParse->db, X); /*A-overwrites-X*/}
+   {A = sql_trigger_select_step(pParse, X); /*A-overwrites-X*/}
 
 // The special RAISE expression that may occur in trigger programs
 expr(A) ::= RAISE(X) LP IGNORE RP(Y).  {
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 498982e01..99c8adbdd 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -4154,12 +4154,69 @@ vdbe_code_row_trigger_direct(struct Parse *parser, struct sql_trigger *trigger,
 			     int ignore_jump);
 
 void sqlDeleteTriggerStep(sql *, TriggerStep *);
-TriggerStep *sqlTriggerSelectStep(sql *, Select *);
-TriggerStep *sqlTriggerInsertStep(sql *, Token *, IdList *,
-				      Select *, u8);
-TriggerStep *sqlTriggerUpdateStep(sql *, Token *, ExprList *, Expr *,
-				      u8);
-TriggerStep *sqlTriggerDeleteStep(sql *, Token *, Expr *);
+
+/**
+ * Turn a SELECT statement (that the pSelect parameter points to)
+ * into a trigger step. Return a pointer to a TriggerStep
+ * structure.
+ * The parser calls this routine when it finds a SELECT statement in
+ * body of a TRIGGER.
+ * @param parser The parsing context.
+ * @param select The SELECT statement to process.
+ * @retval not NULL TriggerStep object on success, NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_select_step(struct Parse *parser, struct Select *select);
+
+/**
+ * Build a trigger step out of an INSERT statement. Return a
+ * pointer to the new trigger step.
+ * The parser calls this routine when it sees an INSERT inside the
+ * body of a trigger.
+ * @param parser The parsing context.
+ * @param table_name Name of the table into which we insert.
+ * @param column_list List of columns in table to insert into.
+ * @param select The SELECT statement that supplies values.
+ * @param orconf The conflict algorithm
+ *               (ON_CONFLICT_ACTION_ABORT, _REPLACE, etc.).
+ * @retval not NULL TriggerStep object on success, NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_insert_step(struct Parse *parser, struct Token *table_name,
+			struct IdList *column_list, struct Select *select,
+			u8 orconf);
+
+/*
+ * Construct a trigger step that implements an UPDATE statement
+ * and return a pointer to that trigger step. The parser calls
+ * this routine when it sees an UPDATE statement inside the body
+ * of a CREATE TRIGGER.
+ * @param parset The parsing context.
+ * @param table_name Name of the table to be updated.
+ * @param new_list The SET clause: list of column and new values.
+ * @param where The WHERE clause.
+ * @param orconf The conflict algorithm
+ *               (ON_CONFLICT_ACTION_ABORT, _REPLACE, etc.).
+ * @retval not NULL TriggerStep object on success, NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_update_step(struct Parse *parser, struct Token *table_name,
+		        struct ExprList *new_list, struct Expr *where,
+			u8 orconf);
+
+/*
+ * Construct a trigger step that implements a DELETE statement and
+ * return a pointer to that trigger step. The parser calls this
+ * routine when it sees a DELETE statement inside the body of a
+ * CREATE TRIGGER.
+ * @param parser The parsing context.
+ * @param table_name The table from which rows are deleted.
+ * @param where The WHERE clause.
+ * @retval not NULL TriggerStep object on success, NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_delete_step(struct Parse *parser, struct Token * table_name,
+			struct Expr *where);
 
 /**
  * Triggers may access values stored in the old.* or new.*
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 2f54754fa..a5b6cb4fd 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -249,142 +249,103 @@ cleanup:
 	sqlDeleteTriggerStep(db, step_list);
 }
 
-/*
- * Turn a SELECT statement (that the pSelect parameter points to) into
- * a trigger step.  Return a pointer to a TriggerStep structure.
- *
- * The parser calls this routine when it finds a SELECT statement in
- * body of a TRIGGER.
- */
-TriggerStep *
-sqlTriggerSelectStep(sql * db, Select * pSelect)
+struct TriggerStep *
+sql_trigger_select_step(struct Parse *parser, struct Select *select)
 {
-	TriggerStep *pTriggerStep =
-	    sqlDbMallocZero(db, sizeof(TriggerStep));
-	if (pTriggerStep == 0) {
-		sql_select_delete(db, pSelect);
+	struct sql *db = parser->db;
+	struct TriggerStep *trigger_step =
+		sqlDbMallocZero(db, sizeof(TriggerStep));
+	if (trigger_step == NULL) {
+		sql_select_delete(db, select);
 		return 0;
 	}
-	pTriggerStep->op = TK_SELECT;
-	pTriggerStep->pSelect = pSelect;
-	pTriggerStep->orconf = ON_CONFLICT_ACTION_DEFAULT;
-	return pTriggerStep;
+	trigger_step->op = TK_SELECT;
+	trigger_step->pSelect = select;
+	trigger_step->orconf = ON_CONFLICT_ACTION_DEFAULT;
+	return trigger_step;
 }
 
 /*
  * Allocate space to hold a new trigger step.  The allocated space
- * holds both the TriggerStep object and the TriggerStep.target.z string.
- *
- * If an OOM error occurs, NULL is returned and db->mallocFailed is set.
+ * holds both the TriggerStep object and the TriggerStep.target.z
+ * string.
+ * @param parser The parsing context.
+ * @param op Trigger opcode.
+ * @param target_name The target name token.
+ * @retval not NULL TriggerStep object on success, NULL otherwise.
  */
-static TriggerStep *
-triggerStepAllocate(sql * db,	/* Database connection */
-		    u8 op,	/* Trigger opcode */
-		    Token * pName	/* The target name */
-    )
+static struct TriggerStep *
+sql_trigger_step_allocate(struct Parse *parser, u8 op,
+			  struct Token *target_name)
 {
-	TriggerStep *pTriggerStep;
-
-	pTriggerStep =
-	    sqlDbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
-	if (pTriggerStep) {
-		char *z = (char *)&pTriggerStep[1];
-		memcpy(z, pName->z, pName->n);
+	struct sql *db = parser->db;
+	struct TriggerStep *trigger_step =
+	    sqlDbMallocZero(db, sizeof(TriggerStep) + target_name->n + 1);
+	if (trigger_step != NULL) {
+		char *z = (char *)&trigger_step[1];
+		memcpy(z, target_name->z, target_name->n);
 		sqlNormalizeName(z);
-		pTriggerStep->zTarget = z;
-		pTriggerStep->op = op;
+		trigger_step->zTarget = z;
+		trigger_step->op = op;
 	}
-	return pTriggerStep;
+	return trigger_step;
 }
 
-/*
- * Build a trigger step out of an INSERT statement.  Return a pointer
- * to the new trigger step.
- *
- * The parser calls this routine when it sees an INSERT inside the
- * body of a trigger.
- */
-TriggerStep *
-sqlTriggerInsertStep(sql * db,	/* The database connection */
-			 Token * pTableName,	/* Name of the table into which we insert */
-			 IdList * pColumn,	/* List of columns in pTableName to insert into */
-			 Select * pSelect,	/* A SELECT statement that supplies values */
-			 u8 orconf	/* The conflict algorithm
-					 * (ON_CONFLICT_ACTION_ABORT, _REPLACE,
-					 * etc.)
-					 */
-    )
+struct TriggerStep *
+sql_trigger_insert_step(struct Parse *parser, struct Token *table_name,
+			struct IdList *column_list, struct Select *select,
+			u8 orconf)
 {
-	TriggerStep *pTriggerStep;
-
-	assert(pSelect != 0 || db->mallocFailed);
-
-	pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
-	if (pTriggerStep) {
-		pTriggerStep->pSelect =
-		    sqlSelectDup(db, pSelect, EXPRDUP_REDUCE);
-		pTriggerStep->pIdList = pColumn;
-		pTriggerStep->orconf = orconf;
+	struct sql *db = parser->db;
+	assert(select != 0 || db->mallocFailed);
+	struct TriggerStep *trigger_step =
+		sql_trigger_step_allocate(parser, TK_INSERT, table_name);
+	if (trigger_step != NULL) {
+		trigger_step->pSelect =
+			sqlSelectDup(db, select, EXPRDUP_REDUCE);
+		trigger_step->pIdList = column_list;
+		trigger_step->orconf = orconf;
 	} else {
-		sqlIdListDelete(db, pColumn);
+		sqlIdListDelete(db, column_list);
 	}
-	sql_select_delete(db, pSelect);
-
-	return pTriggerStep;
+	sql_select_delete(db, select);
+	return trigger_step;
 }
 
-/*
- * Construct a trigger step that implements an UPDATE statement and return
- * a pointer to that trigger step.  The parser calls this routine when it
- * sees an UPDATE statement inside the body of a CREATE TRIGGER.
- */
-TriggerStep *
-sqlTriggerUpdateStep(sql * db,	/* The database connection */
-			 Token * pTableName,	/* Name of the table to be updated */
-			 ExprList * pEList,	/* The SET clause: list of column and new values */
-			 Expr * pWhere,	/* The WHERE clause */
-			 u8 orconf	/* The conflict algorithm.
-					 * (ON_CONFLICT_ACTION_ABORT, _IGNORE,
-					 * etc)
-					 */
-    )
+struct TriggerStep *
+sql_trigger_update_step(struct Parse *parser, struct Token *table_name,
+		        struct ExprList *new_list, struct Expr *where,
+			u8 orconf)
 {
-	TriggerStep *pTriggerStep;
-
-	pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
-	if (pTriggerStep) {
-		pTriggerStep->pExprList =
-		    sql_expr_list_dup(db, pEList, EXPRDUP_REDUCE);
-		pTriggerStep->pWhere =
-		    sqlExprDup(db, pWhere, EXPRDUP_REDUCE);
-		pTriggerStep->orconf = orconf;
+	struct sql *db = parser->db;
+	struct TriggerStep *trigger_step =
+		sql_trigger_step_allocate(parser, TK_UPDATE, table_name);
+	if (trigger_step != NULL) {
+		trigger_step->pExprList =
+		    sql_expr_list_dup(db, new_list, EXPRDUP_REDUCE);
+		trigger_step->pWhere =
+		    sqlExprDup(db, where, EXPRDUP_REDUCE);
+		trigger_step->orconf = orconf;
 	}
-	sql_expr_list_delete(db, pEList);
-	sql_expr_delete(db, pWhere, false);
-	return pTriggerStep;
+	sql_expr_list_delete(db, new_list);
+	sql_expr_delete(db, where, false);
+	return trigger_step;
 }
 
-/*
- * Construct a trigger step that implements a DELETE statement and return
- * a pointer to that trigger step.  The parser calls this routine when it
- * sees a DELETE statement inside the body of a CREATE TRIGGER.
- */
-TriggerStep *
-sqlTriggerDeleteStep(sql * db,	/* Database connection */
-			 Token * pTableName,	/* The table from which rows are deleted */
-			 Expr * pWhere	/* The WHERE clause */
-    )
+struct TriggerStep *
+sql_trigger_delete_step(struct Parse *parser, struct Token * table_name,
+			struct Expr *where)
 {
-	TriggerStep *pTriggerStep;
-
-	pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
-	if (pTriggerStep) {
-		pTriggerStep->pWhere =
-		    sqlExprDup(db, pWhere, EXPRDUP_REDUCE);
-		pTriggerStep->orconf = ON_CONFLICT_ACTION_DEFAULT;
+	struct sql *db = parser->db;
+	struct TriggerStep *trigger_step =
+		sql_trigger_step_allocate(parser, TK_DELETE, table_name);
+	if (trigger_step != NULL) {
+		trigger_step->pWhere =
+		    sqlExprDup(db, where, EXPRDUP_REDUCE);
+		trigger_step->orconf = ON_CONFLICT_ACTION_DEFAULT;
 	}
-	sql_expr_delete(db, pWhere, false);
-	return pTriggerStep;
+	sql_expr_delete(db, where, false);
+	return trigger_step;
 }
 
 void
-- 
2.20.1





More information about the Tarantool-patches mailing list