[tarantool-patches] Re: [PATCH v1 3/3] box: local sql_flags for parser and vdbe

Kirill Shcherbatov kshcherbatov at tarantool.org
Wed May 15 21:54:52 MSK 2019


The sql_flags is a parser parameter that describe how to parse the
SQL request, but now this information is taken from the global
user session object.
When we need to run the parser with some other parameters, it is
necessary to change global session object, which may lead to
unpredictable consequences in general case.
Introduced a new parser and vdbe field sql_flags is responsible
for SQL parsing results.

Needed for #3691
---
 src/box/sql.c               |  2 +-
 src/box/sql.h               |  3 +-
 src/box/sql/delete.c        | 12 +++---
 src/box/sql/expr.c          |  7 ++--
 src/box/sql/fk_constraint.c |  7 +---
 src/box/sql/insert.c        | 18 ++++-----
 src/box/sql/prepare.c       |  5 ++-
 src/box/sql/select.c        | 24 +++++------
 src/box/sql/sqlInt.h        |  5 ++-
 src/box/sql/tokenize.c      |  7 ++--
 src/box/sql/trigger.c       | 13 +++---
 src/box/sql/update.c        | 15 ++++---
 src/box/sql/vdbe.c          | 79 +++++++++++++++++--------------------
 src/box/sql/vdbeInt.h       |  2 +
 src/box/sql/where.c         | 13 +++---
 15 files changed, 99 insertions(+), 113 deletions(-)

diff --git a/src/box/sql.c b/src/box/sql.c
index fbfa59992..385676055 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -1354,7 +1354,7 @@ sql_checks_resolve_space_def_reference(ExprList *expr_list,
 				       struct space_def *def)
 {
 	Parse parser;
-	sql_parser_create(&parser, sql_get());
+	sql_parser_create(&parser, sql_get(), default_flags);
 	parser.parse_only = true;
 
 	sql_resolve_self_reference(&parser, def, NC_IsCheck, NULL, expr_list);
diff --git a/src/box/sql.h b/src/box/sql.h
index 262a48bcb..15ef74b19 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -327,9 +327,10 @@ sql_checks_update_space_def_reference(struct ExprList *expr_list,
  * which is also cleared in the destroy function.
  * @param parser object to initialize.
  * @param db sql object.
+ * @param sql_flags flags to control parser behaviour.
  */
 void
-sql_parser_create(struct Parse *parser, struct sql *db);
+sql_parser_create(struct Parse *parser, struct sql *db, uint32_t sql_flags);
 
 /**
  * Release the parser object resources.
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index a95b07155..bde70a4d3 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -30,7 +30,6 @@
  */
 
 #include "box/box.h"
-#include "box/session.h"
 #include "box/schema.h"
 #include "sqlInt.h"
 #include "tarantoolInt.h"
@@ -151,7 +150,8 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
 	struct space *space = sql_lookup_space(parse, tab_list->a);
 	if (space == NULL)
 		goto delete_from_cleanup;
-	trigger_list = sql_triggers_exist(space->def, TK_DELETE, NULL, NULL);
+	trigger_list = sql_triggers_exist(parse, space->def, TK_DELETE,
+					  NULL, NULL);
 	bool is_complex = trigger_list != NULL || fk_constraint_is_required(space, NULL);
 	bool is_view = space->def->opts.is_view;
 
@@ -195,8 +195,8 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
 	 * if we are counting rows.
 	 */
 	int reg_count = -1;
-	struct session *user_session = current_session();
-	if (user_session->sql_flags & SQL_CountRows) {
+	uint32_t sql_flags = parse->sql_flags;
+	if ((sql_flags & SQL_CountRows) != 0) {
 		reg_count = ++parse->nMem;
 		sqlVdbeAddOp2(v, OP_Integer, 0, reg_count);
 	}
@@ -287,7 +287,7 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
 		/* Keep track of the number of rows to be
 		 * deleted.
 		 */
-		if (user_session->sql_flags & SQL_CountRows)
+		if ((sql_flags & SQL_CountRows) != 0)
 			sqlVdbeAddOp2(v, OP_AddImm, reg_count, 1);
 
 		/* Extract the primary key for the current row */
@@ -417,7 +417,7 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
 	}
 
 	/* Return the number of rows that were deleted. */
-	if ((user_session->sql_flags & SQL_CountRows) != 0 &&
+	if ((sql_flags & SQL_CountRows) != 0 &&
 	    parse->triggered_space != NULL) {
 		sqlVdbeAddOp2(v, OP_ResultRow, reg_count, 1);
 		sqlVdbeSetNumCols(v, 1);
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index f7507938d..81bcc7839 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -3456,8 +3456,7 @@ sqlExprCachePush(Parse * pParse)
 	struct session MAYBE_UNUSED *user_session;
 	pParse->iCacheLevel++;
 #ifdef SQL_DEBUG
-	user_session = current_session();
-	if (user_session->sql_flags & SQL_VdbeAddopTrace) {
+	if ((pParse->sql_flags & SQL_VdbeAddopTrace) != 0) {
 		printf("PUSH to %d\n", pParse->iCacheLevel);
 	}
 #endif
@@ -3477,7 +3476,7 @@ sqlExprCachePop(Parse * pParse)
 	assert(pParse->iCacheLevel >= 1);
 	pParse->iCacheLevel--;
 #ifdef SQL_DEBUG
-	if (user_session->sql_flags & SQL_VdbeAddopTrace) {
+	if ((pParse->sql_flags & SQL_VdbeAddopTrace) != 0) {
 		printf("POP  to %d\n", pParse->iCacheLevel);
 	}
 #endif
@@ -3566,7 +3565,7 @@ sqlExprCacheClear(Parse * pParse)
 	user_session = current_session();
 
 #if SQL_DEBUG
-	if (user_session->sql_flags & SQL_VdbeAddopTrace) {
+	if ((pParse->sql_flags & SQL_VdbeAddopTrace) != 0) {
 		printf("CLEAR\n");
 	}
 #endif
diff --git a/src/box/sql/fk_constraint.c b/src/box/sql/fk_constraint.c
index 8151c66e5..3bcc0fd24 100644
--- a/src/box/sql/fk_constraint.c
+++ b/src/box/sql/fk_constraint.c
@@ -37,7 +37,6 @@
 #include "sqlInt.h"
 #include "box/fk_constraint.h"
 #include "box/schema.h"
-#include "box/session.h"
 
 /*
  * Deferred and Immediate FKs
@@ -274,9 +273,8 @@ fk_constraint_lookup_parent(struct Parse *parse_context, struct space *parent,
 		sqlReleaseTempReg(parse_context, rec_reg);
 		sqlReleaseTempRange(parse_context, temp_regs, field_count);
 	}
-	struct session *session = current_session();
 	if (!fk_def->is_deferred &&
-	    (session->sql_flags & SQL_DeferFKs) == 0 &&
+	    (parse_context->sql_flags & SQL_DeferFKs) == 0 &&
 	    parse_context->pToplevel == NULL && !parse_context->isMultiWrite) {
 		/*
 		 * If this is an INSERT statement that will insert
@@ -536,7 +534,6 @@ fk_constraint_emit_check(struct Parse *parser, struct space *space, int reg_old,
 {
 	bool is_update = changed_cols != NULL;
 	struct sql *db = parser->db;
-	struct session *user_session = current_session();
 
 	/*
 	 * Exactly one of reg_old and reg_new should be non-zero.
@@ -600,7 +597,7 @@ fk_constraint_emit_check(struct Parse *parser, struct space *space, int reg_old,
 					       changed_cols))
 			continue;
 		if (!fk_def->is_deferred &&
-		    (user_session->sql_flags & SQL_DeferFKs) == 0 &&
+		    (parser->sql_flags & SQL_DeferFKs) == 0 &&
 		    parser->pToplevel == NULL && !parser->isMultiWrite) {
 			assert(reg_old == 0 && reg_new != 0);
 			/*
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index c2aac553f..010695067 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -36,7 +36,6 @@
 #include "sqlInt.h"
 #include "tarantoolInt.h"
 #include "vdbeInt.h"
-#include "box/session.h"
 #include "box/schema.h"
 #include "bit/bit.h"
 #include "box/box.h"
@@ -262,7 +261,6 @@ sqlInsert(Parse * pParse,	/* Parser context */
 	u8 useTempTable = 0;	/* Store SELECT results in intermediate table */
 	u8 bIdListInOrder;	/* True if IDLIST is in table order */
 	ExprList *pList = 0;	/* List of VALUES() to be inserted  */
-	struct session *user_session = current_session();
 
 	/* Register allocations */
 	int regFromSelect = 0;	/* Base register for data coming from SELECT */
@@ -308,7 +306,8 @@ sqlInsert(Parse * pParse,	/* Parser context */
 	 * inserted into is a view
 	 */
 	struct space_def *space_def = space->def;
-	trigger = sql_triggers_exist(space_def, TK_INSERT, NULL, &tmask);
+	trigger = sql_triggers_exist(pParse, space_def, TK_INSERT, NULL,
+				     &tmask);
 
 	bool is_view = space_def->opts.is_view;
 	assert((trigger != NULL && tmask != 0) ||
@@ -529,7 +528,7 @@ sqlInsert(Parse * pParse,	/* Parser context */
 
 	/* Initialize the count of rows to be inserted
 	 */
-	if (user_session->sql_flags & SQL_CountRows) {
+	if ((pParse->sql_flags & SQL_CountRows) != 0) {
 		regRowCount = ++pParse->nMem;
 		sqlVdbeAddOp2(v, OP_Integer, 0, regRowCount);
 	}
@@ -761,7 +760,7 @@ sqlInsert(Parse * pParse,	/* Parser context */
 
 	/* Update the count of rows that are inserted
 	 */
-	if ((user_session->sql_flags & SQL_CountRows) != 0) {
+	if ((pParse->sql_flags & SQL_CountRows) != 0) {
 		sqlVdbeAddOp2(v, OP_AddImm, regRowCount, 1);
 	}
 
@@ -790,7 +789,7 @@ sqlInsert(Parse * pParse,	/* Parser context */
  insert_end:
 
 	/* Return the number of rows inserted. */
-	if ((user_session->sql_flags & SQL_CountRows) != 0 &&
+	if ((pParse->sql_flags & SQL_CountRows) != 0 &&
 	    pParse->triggered_space == NULL) {
 		sqlVdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
 		sqlVdbeSetNumCols(v, 1);
@@ -1039,8 +1038,8 @@ process_index:  ;
 					     part_count);
 			sql_set_multi_write(parse_context, true);
 			struct sql_trigger *trigger =
-				sql_triggers_exist(space->def, TK_DELETE, NULL,
-						   NULL);
+				sql_triggers_exist(parse_context, space->def,
+						   TK_DELETE, NULL, NULL);
 			sql_generate_row_delete(parse_context, space, trigger,
 						cursor, idx_key_reg, part_count,
 						true,
@@ -1130,7 +1129,6 @@ xferOptimization(Parse * pParse,	/* Parser context */
 	int addr1;		/* Loop addresses */
 	int emptyDestTest = 0;	/* Address of test for empty pDest */
 	int regData, regTupleid;	/* Registers holding data and tupleid */
-	struct session *user_session = current_session();
 	bool is_err_action_default = false;
 
 	if (pSelect == NULL)
@@ -1260,7 +1258,7 @@ xferOptimization(Parse * pParse,	/* Parser context */
 	 */
 	if (!rlist_empty(&dest->child_fk_constraint))
 		return 0;
-	if ((user_session->sql_flags & SQL_CountRows) != 0) {
+	if ((pParse->sql_flags & SQL_CountRows) != 0) {
 		return 0;	/* xfer opt does not play well with PRAGMA count_changes */
 	}
 
diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index 3df6b5c36..ad4c71cb6 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -54,7 +54,7 @@ sqlPrepare(sql * db,	/* Database handle. */
 {
 	int rc = SQL_OK;	/* Result code */
 	Parse sParse;		/* Parsing context */
-	sql_parser_create(&sParse, db);
+	sql_parser_create(&sParse, db, current_session()->sql_flags);
 	sParse.pReprepare = pReprepare;
 	assert(ppStmt && *ppStmt == 0);
 	/* assert( !db->mallocFailed ); // not true with SQL_USE_ALLOCA */
@@ -281,10 +281,11 @@ sql_prepare_v2(sql * db,	/* Database handle. */
 }
 
 void
-sql_parser_create(struct Parse *parser, sql *db)
+sql_parser_create(struct Parse *parser, struct sql *db, uint32_t sql_flags)
 {
 	memset(parser, 0, sizeof(struct Parse));
 	parser->db = db;
+	parser->sql_flags = sql_flags;
 	rlist_create(&parser->record_list);
 	region_create(&parser->region, &cord()->slabc);
 }
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index d3472a922..d7376ae11 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -40,7 +40,6 @@
 #include "box/box.h"
 #include "box/coll_id_cache.h"
 #include "box/schema.h"
-#include "box/session.h"
 
 /*
  * Trace output macros
@@ -169,8 +168,6 @@ sqlSelectNew(Parse * pParse,	/* Parsing context */
 			pParse->is_aborted = true;
 		pEList = sql_expr_list_append(db, NULL, expr);
 	}
-	struct session MAYBE_UNUSED *user_session;
-	user_session = current_session();
 	pNew->pEList = pEList;
 	pNew->op = TK_SELECT;
 	pNew->selFlags = selFlags;
@@ -178,7 +175,7 @@ sqlSelectNew(Parse * pParse,	/* Parsing context */
 	pNew->iOffset = 0;
 #ifdef SQL_DEBUG
 	pNew->zSelName[0] = 0;
-	if (user_session->sql_flags & SQL_SelectTrace)
+	if ((pParse->sql_flags & SQL_SelectTrace) != 0)
 		sqlSelectTrace = 0xfff;
 	else
 		sqlSelectTrace = 0;
@@ -1733,7 +1730,6 @@ generateColumnNames(Parse * pParse,	/* Parser context */
 	int i, j;
 	sql *db = pParse->db;
 	int fullNames, shortNames;
-	struct session *user_session = current_session();
 	/* If this is an EXPLAIN, skip this step */
 	if (pParse->explain) {
 		return;
@@ -1751,8 +1747,8 @@ generateColumnNames(Parse * pParse,	/* Parser context */
 	}
 	assert(pTabList != 0);
 	pParse->colNamesSet = 1;
-	fullNames = (user_session->sql_flags & SQL_FullColNames) != 0;
-	shortNames = (user_session->sql_flags & SQL_ShortColNames) != 0;
+	fullNames = (pParse->sql_flags & SQL_FullColNames) != 0;
+	shortNames = (pParse->sql_flags & SQL_ShortColNames) != 0;
 	sqlVdbeSetNumCols(v, pEList->nExpr);
 	uint32_t var_count = 0;
 	for (i = 0; i < pEList->nExpr; i++) {
@@ -1994,18 +1990,16 @@ struct space *
 sqlResultSetOfSelect(Parse * pParse, Select * pSelect)
 {
 	sql *db = pParse->db;
-	uint32_t savedFlags;
-	struct session *user_session = current_session();
 
-	savedFlags = user_session->sql_flags;
-	user_session->sql_flags |= ~SQL_FullColNames;
-	user_session->sql_flags &= SQL_ShortColNames;
+	uint32_t saved_flags = pParse->sql_flags;
+	pParse->sql_flags |= ~SQL_FullColNames;
+	pParse->sql_flags &= SQL_ShortColNames;
 	sqlSelectPrep(pParse, pSelect, 0);
 	if (pParse->is_aborted)
 		return NULL;
 	while (pSelect->pPrior)
 		pSelect = pSelect->pPrior;
-	user_session->sql_flags = savedFlags;
+	pParse->sql_flags = saved_flags;
 	struct space *space = sql_ephemeral_space_new(pParse, NULL);
 	if (space == NULL)
 		return NULL;
@@ -2030,6 +2024,7 @@ allocVdbe(Parse * pParse)
 	Vdbe *v = pParse->pVdbe = sqlVdbeCreate(pParse);
 	if (v == NULL)
 		return NULL;
+	v->sql_flags = pParse->sql_flags;
 	sqlVdbeAddOp2(v, OP_Init, 0, 1);
 	if (pParse->pToplevel == 0
 	    && OptimizationEnabled(pParse->db, SQL_FactorOutConst)
@@ -4782,7 +4777,6 @@ selectExpander(Walker * pWalker, Select * p)
 	sql *db = pParse->db;
 	Expr *pE, *pRight, *pExpr;
 	u16 selFlags = p->selFlags;
-	struct session *user_session = current_session();
 
 	p->selFlags |= SF_Expanded;
 	if (db->mallocFailed) {
@@ -4917,7 +4911,7 @@ selectExpander(Walker * pWalker, Select * p)
 		 */
 		struct ExprList_item *a = pEList->a;
 		ExprList *pNew = 0;
-		uint32_t flags = user_session->sql_flags;
+		uint32_t flags = pParse->sql_flags;
 		int longNames = (flags & SQL_FullColNames) != 0
 		    && (flags & SQL_ShortColNames) == 0;
 
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 9384ec9e8..1b3f9afd1 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -2693,6 +2693,8 @@ struct Parse {
 	bool parse_only;
 	/** Type of parsed_ast member. */
 	enum ast_type parsed_ast_type;
+	/** SQL parsing flags. */
+	uint32_t sql_flags;
 	/**
 	 * Members of this union are valid only
 	 * if parse_only is set to true.
@@ -4023,6 +4025,7 @@ vdbe_code_drop_trigger(struct Parse *parser, const char *trigger_name,
  * table, and, if that operation is an UPDATE, if at least one
  * of the columns in changes_list is being modified.
  *
+ * @param parser Parser context.
  * @param space_def The definition of the space that contains
  *        the triggers.
  * @param op operation one of TK_DELETE, TK_INSERT, TK_UPDATE.
@@ -4030,7 +4033,7 @@ vdbe_code_drop_trigger(struct Parse *parser, const char *trigger_name,
  * @param[out] pMask Mask of TRIGGER_BEFORE|TRIGGER_AFTER
  */
 struct sql_trigger *
-sql_triggers_exist(struct space_def *space_def, int op,
+sql_triggers_exist(struct Parse *parser, struct space_def *space_def, int op,
 		   struct ExprList *changes_list, int *mask_ptr);
 
 /**
diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c
index 8cc35323c..11ef7b97e 100644
--- a/src/box/sql/tokenize.c
+++ b/src/box/sql/tokenize.c
@@ -40,6 +40,7 @@
 #include <unicode/utf8.h>
 #include <unicode/uchar.h>
 
+#include "box/session.h"
 #include "say.h"
 #include "sqlInt.h"
 #include "tarantoolInt.h"
@@ -544,7 +545,7 @@ sql_expr_compile(sql *db, const char *expr, int expr_len)
 	int len = strlen(outer) + expr_len;
 
 	struct Parse parser;
-	sql_parser_create(&parser, db);
+	sql_parser_create(&parser, db, default_flags);
 	parser.parse_only = true;
 
 	struct Expr *expression = NULL;
@@ -569,7 +570,7 @@ struct Select *
 sql_view_compile(struct sql *db, const char *view_stmt)
 {
 	struct Parse parser;
-	sql_parser_create(&parser, db);
+	sql_parser_create(&parser, db, default_flags);
 	parser.parse_only = true;
 
 	struct Select *select = NULL;
@@ -590,7 +591,7 @@ struct sql_trigger *
 sql_trigger_compile(struct sql *db, const char *sql)
 {
 	struct Parse parser;
-	sql_parser_create(&parser, db);
+	sql_parser_create(&parser, db, default_flags);
 	parser.parse_only = true;
 	struct sql_trigger *trigger = NULL;
 	if (sqlRunParser(&parser, sql) == 0 &&
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 14e4198a8..97f69696c 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -37,7 +37,6 @@
 #include "sqlInt.h"
 #include "tarantoolInt.h"
 #include "vdbeInt.h"
-#include "box/session.h"
 
 /* See comment in sqlInt.h */
 int sqlSubProgramsRemaining;
@@ -533,13 +532,12 @@ checkColumnOverlap(IdList * pIdList, ExprList * pEList)
 }
 
 struct sql_trigger *
-sql_triggers_exist(struct space_def *space_def, int op,
+sql_triggers_exist(struct Parse *parser, struct space_def *space_def, int op,
 		   struct ExprList *changes_list, int *mask_ptr)
 {
 	int mask = 0;
 	struct sql_trigger *trigger_list = NULL;
-	struct session *user_session = current_session();
-	if ((user_session->sql_flags & SQL_EnableTrigger) != 0)
+	if ((parser->sql_flags & SQL_EnableTrigger) != 0)
 		trigger_list = space_trigger_list(space_def->id);
 	for (struct sql_trigger *p = trigger_list; p != NULL; p = p->next) {
 		if (p->op == op && checkColumnOverlap(p->pColumns,
@@ -753,7 +751,7 @@ sql_row_trigger_program(struct Parse *parser, struct sql_trigger *trigger,
 	pSubParse = sqlStackAllocZero(db, sizeof(Parse));
 	if (!pSubParse)
 		return 0;
-	sql_parser_create(pSubParse, db);
+	sql_parser_create(pSubParse, db, parser->sql_flags);
 	memset(&sNC, 0, sizeof(sNC));
 	sNC.pParse = pSubParse;
 	pSubParse->triggered_space = space;
@@ -893,9 +891,8 @@ vdbe_code_row_trigger_direct(struct Parse *parser, struct sql_trigger *trigger,
 	if (pPrg == NULL)
 		return;
 
-	struct session *user_session = current_session();
-	bool is_recursive = (trigger->zName && !(user_session->sql_flags &
-						 SQL_RecTriggers));
+	bool is_recursive =
+		trigger->zName && (parser->sql_flags & SQL_RecTriggers) == 0;
 
 	sqlVdbeAddOp4(v, OP_Program, reg, ignore_jump,
 			  ++parser->nMem, (const char *)pPrg->pProgram,
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 35c001939..40b103243 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -34,7 +34,6 @@
  * to handle UPDATE statements.
  */
 #include "sqlInt.h"
-#include "box/session.h"
 #include "tarantoolInt.h"
 #include "box/tuple_format.h"
 #include "box/schema.h"
@@ -92,7 +91,6 @@ sqlUpdate(Parse * pParse,		/* The parser context */
 	int hasFK;		/* True if foreign key processing is required */
 	int labelBreak;		/* Jump here to break out of UPDATE loop */
 	int labelContinue;	/* Jump here to continue next step of UPDATE loop */
-	struct session *user_session = current_session();
 
 	bool is_view;		/* True when updating a view (INSTEAD OF trigger) */
 	/* List of triggers on pTab, if required. */
@@ -127,7 +125,8 @@ sqlUpdate(Parse * pParse,		/* The parser context */
 	/* Figure out if we have any triggers and if the table being
 	 * updated is a view.
 	 */
-	trigger = sql_triggers_exist(space->def, TK_UPDATE, pChanges, &tmask);
+	trigger = sql_triggers_exist(pParse, space->def, TK_UPDATE, pChanges,
+				     &tmask);
 	is_view = space->def->opts.is_view;
 	assert(trigger != NULL || tmask == 0);
 
@@ -298,8 +297,8 @@ sqlUpdate(Parse * pParse,		/* The parser context */
 
 	/* Initialize the count of updated rows
 	 */
-	if ((user_session->sql_flags & SQL_CountRows)
-	    && pParse->triggered_space == NULL) {
+	if ((pParse->sql_flags & SQL_CountRows) != 0 &&
+	    pParse->triggered_space == NULL) {
 		regRowCount = ++pParse->nMem;
 		sqlVdbeAddOp2(v, OP_Integer, 0, regRowCount);
 	}
@@ -500,8 +499,8 @@ sqlUpdate(Parse * pParse,		/* The parser context */
 
 	/* Increment the row counter
 	 */
-	if ((user_session->sql_flags & SQL_CountRows)
-	    && pParse->triggered_space == NULL) {
+	if ((pParse->sql_flags & SQL_CountRows) != 0 &&
+	     pParse->triggered_space == NULL) {
 		sqlVdbeAddOp2(v, OP_AddImm, regRowCount, 1);
 	}
 
@@ -522,7 +521,7 @@ sqlUpdate(Parse * pParse,		/* The parser context */
 	sqlVdbeResolveLabel(v, labelBreak);
 
 	/* Return the number of rows that were changed. */
-	if (user_session->sql_flags & SQL_CountRows &&
+	if ((pParse->sql_flags & SQL_CountRows) != 0 &&
 	    pParse->triggered_space == NULL) {
 		sqlVdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
 		sqlVdbeSetNumCols(v, 1);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index a34395cdf..11f5685f3 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -43,7 +43,6 @@
 #include "box/error.h"
 #include "box/fk_constraint.h"
 #include "box/txn.h"
-#include "box/session.h"
 #include "sqlInt.h"
 #include "vdbeInt.h"
 #include "tarantoolInt.h"
@@ -524,10 +523,10 @@ registerTrace(int iReg, Mem *p) {
 #endif
 
 #ifdef SQL_DEBUG
-#  define REGISTER_TRACE(R,M)						\
-	if(user_session->sql_flags&SQL_VdbeTrace) registerTrace(R,M);
+#  define REGISTER_TRACE(P,R,M)					\
+	if(P->sql_flags&SQL_VdbeTrace) registerTrace(R,M);
 #else
-#  define REGISTER_TRACE(R,M)
+#  define REGISTER_TRACE(P,R,M)
 #endif
 
 
@@ -643,7 +642,6 @@ int sqlVdbeExec(Vdbe *p)
 #ifdef VDBE_PROFILE
 	u64 start;                 /* CPU clock count at start of opcode */
 #endif
-	struct session *user_session = current_session();
 	/*** INSERT STACK UNION HERE ***/
 
 	assert(p->magic==VDBE_MAGIC_RUN);  /* sql_step() verifies this */
@@ -669,20 +667,18 @@ int sqlVdbeExec(Vdbe *p)
 #endif
 #ifdef SQL_DEBUG
 	sqlBeginBenignMalloc();
-	if (p->pc==0
-	    && (user_session->sql_flags&
-		(SQL_VdbeListing|SQL_VdbeEQP|SQL_VdbeTrace))!=0
-		) {
+	if (p->pc == 0 &&
+	    (p->sql_flags & (SQL_VdbeListing|SQL_VdbeEQP|SQL_VdbeTrace)) != 0) {
 		int i;
 		int once = 1;
 		sqlVdbePrintSql(p);
-		if (user_session->sql_flags & SQL_VdbeListing) {
+		if ((p->sql_flags & SQL_VdbeListing) != 0) {
 			printf("VDBE Program Listing:\n");
 			for(i=0; i<p->nOp; i++) {
 				sqlVdbePrintOp(stdout, i, &aOp[i]);
 			}
 		}
-		if (user_session->sql_flags & SQL_VdbeEQP) {
+		if ((p->sql_flags & SQL_VdbeEQP) != 0) {
 			for(i=0; i<p->nOp; i++) {
 				if (aOp[i].opcode==OP_Explain) {
 					if (once) printf("VDBE Query Plan:\n");
@@ -691,7 +687,8 @@ int sqlVdbeExec(Vdbe *p)
 				}
 			}
 		}
-		if (user_session->sql_flags & SQL_VdbeTrace)  printf("VDBE Trace:\n");
+		if ((p->sql_flags & SQL_VdbeTrace) != 0)
+			printf("VDBE Trace:\n");
 	}
 	sqlEndBenignMalloc();
 #endif
@@ -713,9 +710,8 @@ int sqlVdbeExec(Vdbe *p)
 		/* Only allow tracing if SQL_DEBUG is defined.
 		 */
 #ifdef SQL_DEBUG
-		if (user_session->sql_flags & SQL_VdbeTrace) {
+		if ((p->sql_flags & SQL_VdbeTrace) != 0)
 			sqlVdbePrintOp(stdout, (int)(pOp - aOp), pOp);
-		}
 #endif
 
 
@@ -728,21 +724,21 @@ int sqlVdbeExec(Vdbe *p)
 				assert(pOp->p1<=(p->nMem+1 - p->nCursor));
 				assert(memIsValid(&aMem[pOp->p1]));
 				assert(sqlVdbeCheckMemInvariants(&aMem[pOp->p1]));
-				REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
+				REGISTER_TRACE(p, pOp->p1, &aMem[pOp->p1]);
 			}
 			if ((opProperty & OPFLG_IN2)!=0) {
 				assert(pOp->p2>0);
 				assert(pOp->p2<=(p->nMem+1 - p->nCursor));
 				assert(memIsValid(&aMem[pOp->p2]));
 				assert(sqlVdbeCheckMemInvariants(&aMem[pOp->p2]));
-				REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
+				REGISTER_TRACE(p, pOp->p2, &aMem[pOp->p2]);
 			}
 			if ((opProperty & OPFLG_IN3)!=0) {
 				assert(pOp->p3>0);
 				assert(pOp->p3<=(p->nMem+1 - p->nCursor));
 				assert(memIsValid(&aMem[pOp->p3]));
 				assert(sqlVdbeCheckMemInvariants(&aMem[pOp->p3]));
-				REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
+				REGISTER_TRACE(p, pOp->p3, &aMem[pOp->p3]);
 			}
 			if ((opProperty & OPFLG_OUT2)!=0) {
 				assert(pOp->p2>0);
@@ -858,7 +854,7 @@ case OP_Gosub: {            /* jump */
 	memAboutToChange(p, pIn1);
 	pIn1->flags = MEM_Int;
 	pIn1->u.i = (int)(pOp-aOp);
-	REGISTER_TRACE(pOp->p1, pIn1);
+	REGISTER_TRACE(p, pOp->p1, pIn1);
 
 	/* Most jump operations do a goto to this spot in order to update
 	 * the pOp pointer.
@@ -945,7 +941,7 @@ case OP_Yield: {            /* in1, jump */
 	pIn1->flags = MEM_Int;
 	pcDest = (int)pIn1->u.i;
 	pIn1->u.i = (int)(pOp - aOp);
-	REGISTER_TRACE(pOp->p1, pIn1);
+	REGISTER_TRACE(p, pOp->p1, pIn1);
 	pOp = &aOp[pcDest];
 	break;
 }
@@ -1312,7 +1308,7 @@ case OP_Move: {
 		}
 #endif
 		Deephemeralize(pOut);
-		REGISTER_TRACE(p2++, pOut);
+		REGISTER_TRACE(p, p2++, pOut);
 		pIn1++;
 		pOut++;
 	}while( --n);
@@ -1340,7 +1336,7 @@ case OP_Copy: {
 #ifdef SQL_DEBUG
 		pOut->pScopyFrom = 0;
 #endif
-		REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
+		REGISTER_TRACE(p, pOp->p2+pOp->p3-n, pOut);
 		if ((n--)==0) break;
 		pOut++;
 		pIn1++;
@@ -1422,7 +1418,7 @@ case OP_ResultRow: {
 	 * transaction. It needs to be rolled back.
 	 */
 	if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
-		assert(user_session->sql_flags&SQL_CountRows);
+		assert((p->sql_flags & SQL_CountRows) != 0);
 		goto abort_due_to_error;
 	}
 
@@ -1441,7 +1437,7 @@ case OP_ResultRow: {
 	 * The statement transaction is never a top-level transaction.  Hence
 	 * the RELEASE call below can never fail.
 	 */
-	assert(p->iStatement==0 || user_session->sql_flags&SQL_CountRows);
+	assert(p->iStatement == 0 || (p->sql_flags & SQL_CountRows) != 0);
 	rc = sqlVdbeCloseStatement(p, SAVEPOINT_RELEASE);
 	assert(rc==SQL_OK);
 
@@ -1459,7 +1455,7 @@ case OP_ResultRow: {
 		assert((pMem[i].flags & MEM_Ephem)==0
 		       || (pMem[i].flags & (MEM_Str|MEM_Blob))==0);
 		sqlVdbeMemNulTerminate(&pMem[i]);
-		REGISTER_TRACE(pOp->p1+i, &pMem[i]);
+		REGISTER_TRACE(p, pOp->p1+i, &pMem[i]);
 	}
 	if (db->mallocFailed) goto no_mem;
 
@@ -1799,7 +1795,7 @@ case OP_Function: {
 #ifdef SQL_DEBUG
 	for(i=0; i<pCtx->argc; i++) {
 		assert(memIsValid(pCtx->argv[i]));
-		REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
+		REGISTER_TRACE(p, pOp->p2+i, pCtx->argv[i]);
 	}
 #endif
 	MemSetTypeFlag(pCtx->pOut, MEM_Null);
@@ -1821,7 +1817,7 @@ case OP_Function: {
 		if (sqlVdbeMemTooBig(pCtx->pOut)) goto too_big;
 	}
 
-	REGISTER_TRACE(pOp->p3, pCtx->pOut);
+	REGISTER_TRACE(p, pOp->p3, pCtx->pOut);
 	UPDATE_MAX_BLOBSIZE(pCtx->pOut);
 	break;
 }
@@ -2133,7 +2129,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
 				iCompare = 1;    /* Operands are not equal */
 				memAboutToChange(p, pOut);
 				MemSetTypeFlag(pOut, MEM_Null);
-				REGISTER_TRACE(pOp->p2, pOut);
+				REGISTER_TRACE(p, pOp->p2, pOut);
 			} else {
 				VdbeBranchTaken(2,3);
 				if (pOp->p5 & SQL_JUMPIFNULL) {
@@ -2249,7 +2245,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
 		}
 		memAboutToChange(p, pOut);
 		mem_set_bool(pOut, res2);
-		REGISTER_TRACE(pOp->p2, pOut);
+		REGISTER_TRACE(p, pOp->p2, pOut);
 	} else {
 		VdbeBranchTaken(res!=0, (pOp->p5 & SQL_NULLEQ)?2:3);
 		if (res2) {
@@ -2351,8 +2347,8 @@ case OP_Compare: {
 		idx = aPermute ? aPermute[i] : i;
 		assert(memIsValid(&aMem[p1+idx]));
 		assert(memIsValid(&aMem[p2+idx]));
-		REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
-		REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
+		REGISTER_TRACE(p, p1+idx, &aMem[p1+idx]);
+		REGISTER_TRACE(p, p2+idx, &aMem[p2+idx]);
 		assert(i < (int)def->part_count);
 		struct coll *coll = def->parts[i].coll;
 		bool is_rev = def->parts[i].sort_order == SORT_ORDER_DESC;
@@ -2783,7 +2779,7 @@ case OP_Column: {
 	if (zData!=pC->aRow) sqlVdbeMemRelease(&sMem);
 			op_column_out:
 	UPDATE_MAX_BLOBSIZE(pDest);
-	REGISTER_TRACE(pOp->p3, pDest);
+	REGISTER_TRACE(p, pOp->p3, pDest);
 	break;
 
 			op_column_error:
@@ -2924,7 +2920,7 @@ case OP_MakeRecord: {
 		goto no_mem;
 	assert(sqlVdbeCheckMemInvariants(pOut));
 	assert(pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor));
-	REGISTER_TRACE(pOp->p3, pOut);
+	REGISTER_TRACE(p, pOp->p3, pOut);
 	UPDATE_MAX_BLOBSIZE(pOut);
 	break;
 }
@@ -3740,7 +3736,8 @@ case OP_Found: {        /* jump, in3 */
 		for(ii=0; ii<r.nField; ii++) {
 			assert(memIsValid(&r.aMem[ii]));
 			assert((r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0);
-			if (ii) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
+			if (ii != 0)
+				REGISTER_TRACE(p, pOp->p3+ii, &r.aMem[ii]);
 		}
 #endif
 		pIdxKey = &r;
@@ -4092,7 +4089,7 @@ case OP_RowData: {
 	rc = sqlCursorPayload(pCrsr, 0, n, pOut->z);
 	if (rc) goto abort_due_to_error;
 	UPDATE_MAX_BLOBSIZE(pOut);
-	REGISTER_TRACE(pOp->p2, pOut);
+	REGISTER_TRACE(p, pOp->p2, pOut);
 	break;
 }
 
@@ -5028,7 +5025,7 @@ case OP_Param: {           /* out2 */
  * statement counter is incremented (immediate foreign key constraints).
  */
 case OP_FkCounter: {
-	if ((user_session->sql_flags & SQL_DeferFKs || pOp->p1 != 0) &&
+	if (((p->sql_flags & SQL_DeferFKs) != 0 || pOp->p1 != 0) &&
 	    !p->auto_commit) {
 		struct txn *txn = in_txn();
 		assert(txn != NULL && txn->psql_txn != NULL);
@@ -5052,7 +5049,7 @@ case OP_FkCounter: {
  * (immediate foreign key constraint violations).
  */
 case OP_FkIfZero: {         /* jump */
-	if ((user_session->sql_flags & SQL_DeferFKs || pOp->p1) &&
+	if (((p->sql_flags & SQL_DeferFKs) != 0 || pOp->p1 != 0) &&
 	    !p->auto_commit) {
 		struct txn *txn = in_txn();
 		assert(txn != NULL && txn->psql_txn != NULL);
@@ -5236,7 +5233,7 @@ case OP_AggStep: {
 #ifdef SQL_DEBUG
 	for(i=0; i<pCtx->argc; i++) {
 		assert(memIsValid(pCtx->argv[i]));
-		REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
+		REGISTER_TRACE(p, pOp->p2+i, pCtx->argv[i]);
 	}
 #endif
 
@@ -5367,11 +5364,9 @@ case OP_Init: {          /* jump */
 		}
 	}
 #ifdef SQL_DEBUG
-	if ((user_session->sql_flags & SQL_SqlTrace)!=0
-	    && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
-		) {
+	if ((p->sql_flags & SQL_SqlTrace) != 0 &&
+	    (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql)) != 0)
 		sqlDebugPrintf("SQL-trace: %s\n", zTrace);
-	}
 #endif /* SQL_DEBUG */
 #endif /* SQL_OMIT_TRACE */
 	assert(pOp->p2>0);
@@ -5444,7 +5439,7 @@ default: {          /* This is really OP_Noop and OP_Explain */
 		assert(pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1]);
 
 #ifdef SQL_DEBUG
-		if (user_session->sql_flags & SQL_VdbeTrace) {
+		if ((p->sql_flags & SQL_VdbeTrace) != 0) {
 			u8 opProperty = sqlOpcodeProperty[pOrigOp->opcode];
 			if (rc!=0) printf("rc=%d\n",rc);
 			if (opProperty & (OPFLG_OUT2)) {
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index a3100e513..86fd92da1 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -446,6 +446,8 @@ struct Vdbe {
 	u32 expmask;		/* Binding to these vars invalidates VM */
 	SubProgram *pProgram;	/* Linked list of all sub-programs used by VM */
 	AuxData *pAuxData;	/* Linked list of auxdata allocations */
+	/** Parser flags with which this object was built. */
+	uint32_t sql_flags;
 	/* Anonymous savepoint for aborts only */
 	Savepoint *anonymous_savepoint;
 #ifdef SQL_ENABLE_STMT_SCANSTATUS
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index 19ee2d03a..edc2074f9 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -43,7 +43,6 @@
 #include "vdbeInt.h"
 #include "whereInt.h"
 #include "box/coll_id_cache.h"
-#include "box/session.h"
 #include "box/schema.h"
 
 /* Forward declaration of methods */
@@ -2832,9 +2831,10 @@ tnt_error:
 	/* Automatic indexes */
 	LogEst rSize = pTab->nRowLogEst;
 	LogEst rLogSize = estLog(rSize);
-	struct session *user_session = current_session();
-	if (!pBuilder->pOrSet	/* Not part of an OR optimization */
-	    && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) == 0 && (user_session->sql_flags & SQL_AutoIndex) != 0 && pSrc->pIBIndex == 0	/* Has no INDEXED BY clause */
+	if (!pBuilder->pOrSet && /* Not pqart of an OR optimization */
+	    (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) == 0 &&
+	    (pWInfo->pParse->sql_flags & SQL_AutoIndex) != 0 &&
+	    pSrc->pIBIndex == 0	/* Has no INDEXED BY clause */
 	    && !pSrc->fg.notIndexed	/* Has no NOT INDEXED clause */
 	    && HasRowid(pTab)	/* Not WITHOUT ROWID table. (FIXME: Why not?) */
 	    &&!pSrc->fg.isCorrelated	/* Not a correlated subquery */
@@ -4241,10 +4241,9 @@ sqlWhereBegin(Parse * pParse,	/* The parser context */
 	sql *db;		/* Database connection */
 	int rc;			/* Return code */
 	u8 bFordelete = 0;	/* OPFLAG_FORDELETE or zero, as appropriate */
-	struct session *user_session = current_session();
 
 #ifdef SQL_DEBUG
-	if (user_session->sql_flags & SQL_WhereTrace)
+	if ((pParse->sql_flags & SQL_WhereTrace) != 0)
 		sqlWhereTrace = 0xfff;
 	else
 		sqlWhereTrace = 0;
@@ -4452,7 +4451,7 @@ sqlWhereBegin(Parse * pParse,	/* The parser context */
 		}
 	}
 	if (pWInfo->pOrderBy == 0 &&
-	    (user_session->sql_flags & SQL_ReverseOrder) != 0) {
+	    (pParse->sql_flags & SQL_ReverseOrder) != 0) {
 		pWInfo->revMask = ALLBITS;
 	}
 	if (pParse->is_aborted || NEVER(db->mallocFailed)) {
-- 
2.21.0





More information about the Tarantool-patches mailing list