[tarantool-patches] Re: [PATCH] sql: refactor primary index creation
n.pettik
korablev at tarantool.org
Fri Jul 20 15:11:39 MSK 2018
Now you also can remove keyConf field from struct Table.
> @@ -931,6 +925,22 @@ sqlite3AddPrimaryKey(Parse * pParse, /* Parsing context */
> }
> if (pList)
> pParse->iPkSortOrder = pList->a[0].sort_order;
> +
> + struct sqlite3 *db = pParse->db;
> + struct ExprList *list;
> + struct Token ipkToken;
> + sqlite3TokenInit(&ipkToken, pTab->def->fields[iCol].name);
> + list = sql_expr_list_append(db, NULL,
> + sqlite3ExprAlloc(db, TK_ID,
> + &ipkToken, 0));
> + if (list == NULL)
> + return;
You don’t need to create list from scratch: sql_create_index accepts
NULL as list of columns and processes it exactly in the same way
(i.e. uses only last column).
> + list->a[0].sort_order = pParse->iPkSortOrder;
> + sql_create_index(pParse, 0, 0, list, pTab->keyConf, 0, 0,
> + SORT_ORDER_ASC, false,
> + SQL_INDEX_TYPE_CONSTRAINT_PK);
> + if (db->mallocFailed)
> + return;
goto primary_key_exit?
> } else if (autoInc) {
> sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
> "INTEGER PRIMARY KEY or INT PRIMARY KEY");
> @@ -941,7 +951,16 @@ sqlite3AddPrimaryKey(Parse * pParse, /* Parsing context */
> pList = 0;
> }
>
> - primary_key_exit:
> + /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
> + */
Fix comment: we don’t have imposter tables; fit it into 66 chars.
> + for (uint32_t i = 0; i < pTab->def->field_count; i++) {
> + if (pTab->aCol[i].is_primkey) {
> + pTab->def->fields[i].nullable_action
> + = ON_CONFLICT_ACTION_ABORT;
> + pTab->def->fields[i].is_nullable = false;
> + }
> + }
> +primary_key_exit:
> sql_expr_list_delete(pParse->db, pList);
> return;
> }
> @@ -1215,63 +1234,6 @@ createTableStmt(sqlite3 * db, Table * p)
> return zStmt;
> }
>
> -/*
> - * This routine runs at the end of parsing a CREATE TABLE statement.
> - * The job of this routine is to convert both
> - * internal schema data structures and the generated VDBE code.
> - * Changes include:
> - *
> - * (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
> - * (2) Set the Index.tnum of the PRIMARY KEY Index object in the
> - * schema to the rootpage from the main table.
> - * (3) Add all table columns to the PRIMARY KEY Index object
> - * so that the PRIMARY KEY is a covering index.
> - */
> -static void
> -convertToWithoutRowidTable(Parse * pParse, Table * pTab)
I see reference to this function in comment to struct Index.
Remove it as well.
>
> @@ -2559,7 +2519,9 @@ tnt_error:
> static bool
> constraint_is_named(const char *name)
> {
> - return strncmp(name, "sql_autoindex_", strlen("sql_autoindex_"));
> + return strncmp(name, "sql_autoindex_", strlen("sql_autoindex_")) &&
> + strncmp(name, "pk_unnamed_", strlen("pk_unnamed_")) &&
> + strncmp(name, "unique_unnamed_", strlen("unique_unnamed_"));
> }
>
> void
> @@ -2648,29 +2610,36 @@ sql_create_index(struct Parse *parse, struct Token *token,
> sqlite3NameFromToken(db,
> &parse->constraintName);
>
> + /*
> + * This naming is temporary. Now it's not
> + * possible (since we implement UNIQUE
> + * and PK constraints with indexes and
> + * indexes can not have same names), but
> + * in future we would use names exactly
> + * as they are set by user.
> + */
> + const char *prefix = "sql_autoindex_%s_%d”;
If we trapped so far, index is definitely UNIQUE or PK constraint,
so this initialisation with default prefix is redundant.
And actually I don’t understand why do you need this renaming...
> + if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_UNIQUE) {
> + prefix = constraint_name == NULL ?
> + "unique_unnamed_%s_%d" : "unique_%s_%d";
> + }
> + else {
> + if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK)
> + prefix = constraint_name == NULL ?
> + "pk_unnamed_%s_%d" : "pk_%s_%d";
> + }
> +
> + uint32_t n = 1;
> + for (struct Index *idx = table->pIndex; idx != NULL;
> + idx = idx->pNext, n++);
> +
> if (constraint_name == NULL ||
> strcmp(constraint_name, "") == 0) {
> - uint32_t n = 1;
> - for (struct Index *idx = table->pIndex; idx != NULL;
> - idx = idx->pNext, n++);
> - name = sqlite3MPrintf(db, "sql_autoindex_%s_%d",
> + name = sqlite3MPrintf(db, prefix,
> table->def->name, n);
> } else {
> - /*
> - * This naming is temporary. Now it's not
> - * possible (since we implement UNIQUE
> - * and PK constraints with indexes and
> - * indexes can not have same names), but
> - * in future we would use names exactly
> - * as they are set by user.
> - */
> - if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_UNIQUE)
> - name = sqlite3MPrintf(db,
> - "unique_constraint_%s",
> - constraint_name);
> - if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK)
> - name = sqlite3MPrintf(db, "pk_constraint_%s",
> - constraint_name);
> + name = sqlite3MPrintf(db, prefix,
> + constraint_name, n);
> }
> sqlite3DbFree(db, constraint_name);
> }
>
> diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
> index 7b1f6ec..cabe22b 100644
> --- a/src/box/sql/pragma.c
> +++ b/src/box/sql/pragma.c
> @@ -726,22 +726,20 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
> int iKey = pFK->aCol[0].iFrom;
> assert(iKey >= 0 && iKey <
> (int)pTab->def->field_count);
> - if (iKey != pTab->iPKey) {
> - sqlite3VdbeAddOp3(v,
> - OP_Column,
> - 0,
> - iKey,
> - regRow);
> - sqlite3ColumnDefault(v,
> - pTab->def,
> - iKey,
> - regRow);
> - sqlite3VdbeAddOp2(v,
> - OP_IsNull,
> - regRow,
> - addrOk);
> - VdbeCoverage(v);
> - }
> + sqlite3VdbeAddOp3(v,
> + OP_Column,
> + 0,
> + iKey,
> + regRow);
> + sqlite3ColumnDefault(v,
> + pTab->def,
> + iKey,
> + regRow);
> + sqlite3VdbeAddOp2(v,
> + OP_IsNull,
> + regRow,
> + addrOk);
> + VdbeCoverage(v);
> VdbeCoverage(v);
Double call of VdbeCoverage();
More information about the Tarantool-patches
mailing list