[tarantool-patches] [PATCH 01/10] sql: remove suport of ALTER TABLE ADD COLUMN

Nikita Pettik korablev at tarantool.org
Sun Aug 12 17:12:57 MSK 2018


We disabled ALTER TABLE ADD COLUMN long ago (i.e. banned in parser
ability to process this statement), but internal functions for handling
this routine have remained. This patch removes them as well.

Part of #3561
---
 src/box/sql/alter.c     | 185 ------------------------------------------------
 src/box/sql/build.c     |  16 +----
 src/box/sql/parse.y     |  12 ++--
 src/box/sql/sqliteInt.h |   7 +-
 4 files changed, 7 insertions(+), 213 deletions(-)

diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c
index c6463c79e..349589be4 100644
--- a/src/box/sql/alter.c
+++ b/src/box/sql/alter.c
@@ -37,12 +37,6 @@
 #include "src/box/session.h"
 #include "tarantoolInt.h"
 
-/*
- * The code in this file only exists if we are not omitting the
- * ALTER TABLE logic from the build.
- */
-#ifndef SQLITE_OMIT_ALTERTABLE
-
 /*
  * Generate code to drop and reload the internal representation of table
  * pTab from the database, including triggers.
@@ -127,183 +121,6 @@ sqlite3AlterRenameTable(Parse * pParse,	/* Parser context. */
 	user_session->sql_flags = savedDbFlags;
 }
 
-/*
- * This function is called after an "ALTER TABLE ... ADD" statement
- * has been parsed. Argument pColDef contains the text of the new
- * column definition.
- *
- * The Table structure pParse->pNewTable was extended to include
- * the new column during parsing.
- */
-void
-sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
-{
-	/* This function is not implemented yet #3075. */
-	unreachable();
-
-	Table *pNew;		/* Copy of pParse->pNewTable */
-	Table *pTab;		/* Table being altered */
-	const char *zTab;	/* Table name */
-	Expr *pDflt;		/* Default value for the new column */
-	sqlite3 *db;		/* The database connection; */
-	Vdbe *v = pParse->pVdbe;	/* The prepared statement under construction */
-
-	db = pParse->db;
-	if (pParse->nErr || db->mallocFailed)
-		return;
-	assert(v != 0);
-	pNew = pParse->pNewTable;
-	assert(pNew);
-
-	/* Skip the "sqlite_altertab_" prefix on the name. */
-	zTab = &pNew->def->name[16];
-	assert(pNew->def != NULL);
-	pDflt = space_column_default_expr(pNew->def->id,
-					  pNew->def->field_count - 1);
-	pTab = sqlite3HashFind(&db->pSchema->tblHash, zTab);;
-	assert(pTab);
-
-	/* If the default value for the new column was specified with a
-	 * literal NULL, then set pDflt to 0. This simplifies checking
-	 * for an SQL NULL default below.
-	 */
-	assert(pDflt == 0 || pDflt->op == TK_SPAN);
-	if (pDflt && pDflt->pLeft->op == TK_NULL) {
-		pDflt = 0;
-	}
-
-	/* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
-	 * If there is a NOT NULL constraint, then the default value for the
-	 * column must not be NULL.
-	 */
-	struct Index *pk = sqlite3PrimaryKeyIndex(pTab);
-	assert(pk != NULL);
-	struct key_def *pk_key_def = pk->def->key_def;
-	if (key_def_find(pk_key_def, pNew->def->field_count - 1) != NULL) {
-		sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
-		return;
-	}
-	if (pNew->pIndex) {
-		sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
-		return;
-	}
-	assert(pNew->def->fields[pNew->def->field_count - 1].is_nullable ==
-	       action_is_nullable(pNew->def->fields[
-		pNew->def->field_count - 1].nullable_action));
-	if (!pNew->def->fields[pNew->def->field_count - 1].is_nullable &&
-	    pDflt == NULL) {
-		sqlite3ErrorMsg(pParse,
-				"Cannot add a NOT NULL column with default value NULL");
-		return;
-	}
-
-	/* Ensure the default expression is something that sqlite3ValueFromExpr()
-	 * can handle (i.e. not CURRENT_TIME etc.)
-	 */
-	if (pDflt) {
-		sqlite3_value *pVal = 0;
-		int rc;
-		rc = sqlite3ValueFromExpr(db, pDflt,
-					  AFFINITY_BLOB, &pVal);
-		assert(rc == SQLITE_OK || rc == SQLITE_NOMEM);
-		if (rc != SQLITE_OK) {
-			assert(db->mallocFailed == 1);
-			return;
-		}
-		if (!pVal) {
-			sqlite3ErrorMsg(pParse,
-					"Cannot add a column with non-constant default");
-			return;
-		}
-		sqlite3ValueFree(pVal);
-	}
-
-	/* Modify the CREATE TABLE statement. */
-	/* TODO: Adopt for Tarantool. */
-	(void)pColDef;
-
-	/* Reload the schema of the modified table. */
-	reloadTableSchema(pParse, pTab, pTab->def->name);
-}
-
-/*
- * This function is called by the parser after the table-name in
- * an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
- * pSrc is the full-name of the table being altered.
- *
- * This routine makes a (partial) copy of the Table structure
- * for the table being altered and sets Parse.pNewTable to point
- * to it. Routines called by the parser as the column definition
- * is parsed (i.e. sqlite3AddColumn()) add the new Column data to
- * the copy. The copy of the Table structure is deleted by tokenize.c
- * after parsing is finished.
- *
- * Routine sqlite3AlterFinishAddColumn() will be called to complete
- * coding the "ALTER TABLE ... ADD" statement.
- */
-void
-sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
-{
-	/* This function is not implemented yet #3075. */
-	unreachable();
-
-	Table *pNew;
-	Table *pTab;
-	Vdbe *v;
-	sqlite3 *db = pParse->db;
-
-	/* Look up the table being altered. */
-	assert(pParse->pNewTable == 0);
-	if (db->mallocFailed)
-		goto exit_begin_add_column;
-	pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName);
-	if (pTab == NULL)
-		goto exit_begin_add_column;
-
-	/* Make sure this is not an attempt to ALTER a view. */
-	if (pTab->def->opts.is_view) {
-		sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
-		goto exit_begin_add_column;
-	}
-
-	assert(pTab->addColOffset > 0);
-
-	/* Put a copy of the Table struct in Parse.pNewTable for the
-	 * sqlite3AddColumn() function and friends to modify.  But modify
-	 * the name by adding an "sqlite_altertab_" prefix.  By adding this
-	 * prefix, we insure that the name will not collide with an existing
-	 * table because user table are not allowed to have the "sqlite_"
-	 * prefix on their name.
-	 */
-	pNew = (Table *) sqlite3DbMallocZero(db, sizeof(Table));
-	if (!pNew)
-		goto exit_begin_add_column;
-	pNew->def = space_def_dup(pTab->def);
-	if (pNew->def == NULL) {
-		sqlite3DbFree(db, pNew);
-		sqlite3OomFault(db);
-		goto exit_begin_add_column;
-	}
-	pParse->pNewTable = pNew;
-	assert(pNew->def->field_count > 0);
-	/* FIXME: pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); */
-	/* FIXME: if (!pNew->aCol || !pNew->zName) { */
-	for (uint32_t i = 0; i < pNew->def->field_count; i++)
-		pNew->def->fields[i] = field_def_default;
-	pNew->pSchema = db->pSchema;
-	pNew->addColOffset = pTab->addColOffset;
-	pNew->nTabRef = 1;
-
-	/* Begin a transaction. */
-	sql_set_multi_write(pParse, false);
-	v = sqlite3GetVdbe(pParse);
-	if (!v)
-		goto exit_begin_add_column;
- exit_begin_add_column:
-	sqlite3SrcListDelete(db, pSrc);
-	return;
-}
-
 /*
  * This function implements part of the ALTER TABLE command.
  * The first argument is the text of a CREATE TABLE or CREATE INDEX command.
@@ -444,5 +261,3 @@ rename_trigger(sqlite3 *db, char const *sql_stmt, char const *table_name,
 				      table_name, tname.z + tname.n);
 	return new_sql_stmt;
 }
-
-#endif				/* SQLITE_ALTER_TABLE */
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index cdf2bfcc9..f3546b794 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -1683,7 +1683,6 @@ resolve_link(struct Parse *parse_context, const struct space_def *def,
  */
 void
 sqlite3EndTable(Parse * pParse,	/* Parse context */
-		Token * pCons,	/* The ',' token after the last column defn. */
 		Token * pEnd,	/* The ')' before options in the CREATE TABLE */
 		Select * pSelect	/* Select from a "CREATE ... AS SELECT" */
     )
@@ -1749,19 +1748,6 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 		}
 		pParse->pNewTable = NULL;
 		current_session()->sql_flags |= SQLITE_InternChanges;
-
-#ifndef SQLITE_OMIT_ALTERTABLE
-		if (!p->def->opts.is_view) {
-			const char *zName = (const char *)pParse->sNameToken.z;
-			int nName;
-			assert(!pSelect && pCons && pEnd);
-			if (pCons->z == 0) {
-				pCons = pEnd;
-			}
-			nName = (int)((const char *)pCons->z - zName);
-			p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName);
-		}
-#endif
 		goto finish;
 	}
 	/*
@@ -1931,7 +1917,7 @@ sql_create_view(struct Parse *parse_context, struct Token *begin,
 	}
 
 	/* Use sqlite3EndTable() to add the view to the Tarantool.  */
-	sqlite3EndTable(parse_context, 0, &end, 0);
+	sqlite3EndTable(parse_context, &end, 0);
 
  create_view_fail:
 	sqlite3DbFree(db, sel_tab);
diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index 200d57a7d..58a6bf39a 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -176,11 +176,11 @@ createkw(A) ::= CREATE(A).  {disableLookaside(pParse);}
 ifnotexists(A) ::= .              {A = 0;}
 ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
 
-create_table_args ::= LP columnlist conslist_opt(X) RP(E). {
-  sqlite3EndTable(pParse,&X,&E,0);
+create_table_args ::= LP columnlist conslist_opt RP(E). {
+  sqlite3EndTable(pParse,&E,0);
 }
 create_table_args ::= AS select(S). {
-  sqlite3EndTable(pParse,0,0,S);
+  sqlite3EndTable(pParse,0,S);
   sql_select_delete(pParse->db, S);
 }
 columnlist ::= columnlist COMMA columnname carglist.
@@ -327,8 +327,8 @@ init_deferred_pred_opt(A) ::= .                       {A = 0;}
 init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
 init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}
 
-conslist_opt(A) ::= .                         {A.n = 0; A.z = 0;}
-conslist_opt(A) ::= COMMA(A) conslist.
+conslist_opt ::= .
+conslist_opt ::= COMMA conslist.
 conslist ::= conslist tconscomma tcons.
 conslist ::= tcons.
 tconscomma ::= COMMA.            {pParse->constraintName.n = 0;}
@@ -1443,7 +1443,6 @@ cmd ::= ANALYZE.                {sqlite3Analyze(pParse, 0);}
 cmd ::= ANALYZE nm(X).          {sqlite3Analyze(pParse, &X);}
 
 //////////////////////// ALTER TABLE table ... ////////////////////////////////
-%ifndef SQLITE_OMIT_ALTERTABLE
 cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). {
   sqlite3AlterRenameTable(pParse,X,&Z);
 }
@@ -1470,7 +1469,6 @@ cmd ::= ALTER TABLE fullname(X) DROP CONSTRAINT nm(Z). {
 /* } */
 /* kwcolumn_opt ::= . */
 /* kwcolumn_opt ::= COLUMNKW. */
-%endif  SQLITE_OMIT_ALTERTABLE
 
 //////////////////////// COMMON TABLE EXPRESSIONS ////////////////////////////
 %type with {With*}
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index 189d16150..ddedfbcb4 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -1888,9 +1888,6 @@ struct Table {
 	 */
 	LogEst tuple_log_count;
 	u8 tabFlags;		/* Mask of TF_* values */
-#ifndef SQLITE_OMIT_ALTERTABLE
-	int addColOffset;	/* Offset in CREATE TABLE stmt to add a new column */
-#endif
 	Schema *pSchema;	/* Schema that contains this table */
 	Table *pNextZombie;	/* Next on the Parse.pZombieTab list */
 	/** Space definition with Tarantool metadata. */
@@ -3501,7 +3498,7 @@ void sqlite3AddCollateType(Parse *, Token *);
 struct coll *
 sql_column_collation(struct space_def *def, uint32_t column, uint32_t *coll_id);
 
-void sqlite3EndTable(Parse *, Token *, Token *, Select *);
+void sqlite3EndTable(Parse *, Token *, Select *);
 
 /**
  * Create cursor which will be positioned to the space/index.
@@ -4525,8 +4522,6 @@ int sqlite3ResolveOrderGroupBy(Parse *, Select *, ExprList *, const char *);
 void
 sqlite3ColumnDefault(Vdbe *v, struct space_def *def, int i, int ireg);
 
-void sqlite3AlterFinishAddColumn(Parse *, Token *);
-void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
 char* rename_table(sqlite3 *, const char *, const char *, bool *);
 char* rename_trigger(sqlite3 *, char const *, char const *, bool *);
 /**
-- 
2.15.1





More information about the Tarantool-patches mailing list