[tarantool-patches] [PATCH v2 5/7] sql: refactor sql_trigger_step_allocate to set diag
Kirill Shcherbatov
kshcherbatov at tarantool.org
Wed Feb 27 14:13:16 MSK 2019
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
More information about the Tarantool-patches
mailing list