Tarantool development patches archive
 help / color / mirror / Atom feed
From: Kirill Shcherbatov <kshcherbatov@tarantool.org>
To: tarantool-patches@freelists.org, v.shpilevoy@tarantool.org
Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org>
Subject: [tarantool-patches] [PATCH v2 5/7] sql: refactor sql_trigger_step_allocate to set diag
Date: Wed, 27 Feb 2019 14:13:16 +0300	[thread overview]
Message-ID: <607ffbbc4fcdca43ccfc5e6dabaed5ca3bc7719f.1551265819.git.kshcherbatov@tarantool.org> (raw)
In-Reply-To: <cover.1551265819.git.kshcherbatov@tarantool.org>

Refactored sql_trigger_step_allocate routine to use diag_set in
case of memory allocation error. Also performed some additional
name refactoring in adjacent places.
This change is necessary because the sql_trigger_step_allocate
body has a sqlNameFromToken call that will be changed in
subsequent patches.

Needed for #3931
---
 src/box/sql/parse.y   |  30 +++++--
 src/box/sql/sqlInt.h  |  73 +++++++++++++++--
 src/box/sql/trigger.c | 187 +++++++++++++++++-------------------------
 3 files changed, 162 insertions(+), 128 deletions(-)

diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index f56b831e5..db03714a9 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -1423,20 +1423,34 @@ tridxby ::= NOT INDEXED. {
 %destructor trigger_cmd {sqlDeleteTriggerStep(pParse->db, $$);}
 // UPDATE 
 trigger_cmd(A) ::=
-   UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z).  
-   {A = sqlTriggerUpdateStep(pParse->db, &X, Y, Z, R);}
+   UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z). {
+     A = sql_trigger_update_step(pParse->db, &X, Y, Z, R);
+     if (A == NULL)
+        sql_parser_error(pParse);
+   }
 
 // 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*/}
+trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) idlist_opt(F) select(S). {
+  /*A-overwrites-R. */
+  A = sql_trigger_insert_step(pParse->db, &X, F, S, R);
+  if (A == NULL)
+    sql_parser_error(pParse);
+}
 
 // DELETE
-trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
-   {A = sqlTriggerDeleteStep(pParse->db, &X, Y);}
+trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y). {
+  A = sql_trigger_delete_step(pParse->db, &X, Y);
+  if (A == NULL)
+    sql_parser_error(pParse);
+}
 
 // SELECT
-trigger_cmd(A) ::= select(X).
-   {A = sqlTriggerSelectStep(pParse->db, X); /*A-overwrites-X*/}
+trigger_cmd(A) ::= select(X). {
+  /* A-overwrites-X. */
+  A = sql_trigger_select_step(pParse->db, X);
+  if (A == NULL)
+    sql_parser_error(pParse);
+}
 
 // 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 10943d3c8..531445f33 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -4146,12 +4146,73 @@ 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 db The database connection.
+ * @param select The SELECT statement to process.
+ * @retval not NULL TriggerStep object on success.
+ * @retval NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_select_step(struct sql *db, 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 db The database connection.
+ * @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.
+ * @retval NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_insert_step(struct sql *db, 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 db The database connection.
+ * @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.
+ * @retval NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_update_step(struct sql *db, 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 db The database connection.
+ * @param table_name The table from which rows are deleted.
+ * @param where The WHERE clause.
+ * @retval not NULL TriggerStep object on success.
+ * @retval NULL otherwise.
+ */
+struct TriggerStep *
+sql_trigger_delete_step(struct sql *db, 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 65218121b..af62a5eff 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -249,142 +249,101 @@ 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 sql *db, struct Select *select)
 {
-	TriggerStep *pTriggerStep =
-	    sqlDbMallocZero(db, sizeof(TriggerStep));
-	if (pTriggerStep == 0) {
-		sql_select_delete(db, pSelect);
-		return 0;
+	struct TriggerStep *trigger_step =
+		sqlDbMallocZero(db, sizeof(TriggerStep));
+	if (trigger_step == NULL) {
+		sql_select_delete(db, select);
+		diag_set(OutOfMemory, sizeof(TriggerStep), "sqlDbMallocZero",
+			 "trigger_step");
+		return NULL;
 	}
-	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 db The database connection.
+ * @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 sql *db, 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);
-		sqlNormalizeName(z);
-		pTriggerStep->zTarget = z;
-		pTriggerStep->op = op;
+	int size = sizeof(TriggerStep) + target_name->n + 1;
+	struct TriggerStep *trigger_step = sqlDbMallocZero(db, size);
+	if (trigger_step == NULL) {
+		diag_set(OutOfMemory, size, "sqlDbMallocZero", "trigger_step");
+		return NULL;
 	}
-	return pTriggerStep;
+	char *z = (char *)&trigger_step[1];
+	memcpy(z, target_name->z, target_name->n);
+	sqlNormalizeName(z);
+	trigger_step->zTarget = z;
+	trigger_step->op = op;
+	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 sql *db, 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;
+	assert(select != 0 || db->mallocFailed);
+	struct TriggerStep *trigger_step =
+		sql_trigger_step_allocate(db, 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 sql *db, 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 TriggerStep *trigger_step =
+		sql_trigger_step_allocate(db, 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 sql *db, 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 TriggerStep *trigger_step =
+		sql_trigger_step_allocate(db, 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

  parent reply	other threads:[~2019-02-27 11:13 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-27 11:13 [tarantool-patches] [PATCH v2 0/7] sql: store regular identifiers in case-normal form Kirill Shcherbatov
2019-02-27 11:13 ` [tarantool-patches] [PATCH v2 1/7] sql: refactor sql_alloc_src_list to set diag Kirill Shcherbatov
2019-03-07 17:34   ` [tarantool-patches] " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-02-27 11:13 ` [tarantool-patches] [PATCH v2 2/7] sql: rework sql_src_list_enlarge " Kirill Shcherbatov
2019-03-07 17:34   ` [tarantool-patches] " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-02-27 11:13 ` [tarantool-patches] [PATCH v2 3/7] sql: refactor sql_src_list_append " Kirill Shcherbatov
2019-03-07 17:34   ` [tarantool-patches] " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-03-18 19:33       ` Vladislav Shpilevoy
2019-03-20 11:02         ` Kirill Shcherbatov
2019-03-26 17:08           ` Vladislav Shpilevoy
2019-03-26 18:07             ` Vladislav Shpilevoy
2019-02-27 11:13 ` [tarantool-patches] [PATCH v2 4/7] sql: refactor sql_name_from_token " Kirill Shcherbatov
2019-03-07 17:34   ` [tarantool-patches] " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-03-18 19:33       ` Vladislav Shpilevoy
2019-03-20 11:02         ` Kirill Shcherbatov
2019-02-27 11:13 ` Kirill Shcherbatov [this message]
2019-03-07 17:34   ` [tarantool-patches] Re: [PATCH v2 5/7] sql: refactor sql_trigger_step_allocate " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-03-18 19:33       ` Vladislav Shpilevoy
2019-03-20 11:02         ` Kirill Shcherbatov
2019-03-26 17:08           ` Vladislav Shpilevoy
2019-02-27 11:13 ` [tarantool-patches] [PATCH v2 6/7] sql: refactor sql_expr_create " Kirill Shcherbatov
2019-03-07 17:34   ` [tarantool-patches] " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-03-18 19:33       ` Vladislav Shpilevoy
2019-03-20 11:02         ` Kirill Shcherbatov
2019-03-26 17:08           ` Vladislav Shpilevoy
2019-02-27 11:13 ` [tarantool-patches] [PATCH v2 7/7] sql: store regular identifiers in case-normal form Kirill Shcherbatov
2019-03-07 17:34   ` [tarantool-patches] " Vladislav Shpilevoy
2019-03-11 15:04     ` Kirill Shcherbatov
2019-03-18 19:33       ` Vladislav Shpilevoy
2019-03-20 11:02         ` Kirill Shcherbatov
2019-03-26 17:08           ` Vladislav Shpilevoy
2019-03-18 19:33 ` [tarantool-patches] Re: [PATCH v2 0/7] " Vladislav Shpilevoy
2019-03-20 11:02   ` Kirill Shcherbatov
2019-03-26 17:09     ` Vladislav Shpilevoy
2019-03-27 14:06 ` 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=607ffbbc4fcdca43ccfc5e6dabaed5ca3bc7719f.1551265819.git.kshcherbatov@tarantool.org \
    --to=kshcherbatov@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [tarantool-patches] [PATCH v2 5/7] sql: refactor sql_trigger_step_allocate to set diag' \
    /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