[patches] [PATCH 3/3] sql: delegate SQL primary key check to Tarantool
Alex Khatskevich
avkhatskevich at tarantool.org
Mon Feb 26 14:13:42 MSK 2018
Ack
On 22.02.2018 17:55, Alex Khatskevich wrote:
>
>
> On 14.02.2018 15:38, Nikita Pettik wrote:
>> As last point of removing colflag attribute from struct Column,
>> table_column_is_primkey() function is added. It checks via Tarantool
>> facilities whether column belongs to PK or not (after space creation).
>> However, during initializing of SQL iternals and before actual creation
>> of struct space, colflag attribute (as indicator of PK) still can be
>> used.
>> Since this is the only purpose of attribute, one has been renamed.
>>
>> Closes #3118
>>
>> Signed-off-by: Nikita Pettik <korablev at tarantool.org>
>> ---
>> src/box/sql/alter.c | 2 +-
>> src/box/sql/build.c | 34 ++++++++++++++++++++++++++++++----
>> src/box/sql/fkey.c | 2 +-
>> src/box/sql/pragma.c | 3 +--
>> src/box/sql/sqliteInt.h | 7 ++-----
>> src/box/sql/update.c | 11 ++++-------
>> 6 files changed, 39 insertions(+), 20 deletions(-)
>>
>> diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c
>> index 2794c52cc..0bab035e0 100644
>> --- a/src/box/sql/alter.c
>> +++ b/src/box/sql/alter.c
>> @@ -231,7 +231,7 @@ sqlite3AlterFinishAddColumn(Parse * pParse, Token
>> * pColDef)
>> * If there is a NOT NULL constraint, then the default value
>> for the
>> * column must not be NULL.
>> */
>> - if (pCol->colFlags & COLFLAG_PRIMKEY) {
>> + if (pCol->is_primkey) {
>> sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
>> return;
>> }
>> diff --git a/src/box/sql/build.c b/src/box/sql/build.c
>> index 851a8f760..8f69901bf 100644
>> --- a/src/box/sql/build.c
>> +++ b/src/box/sql/build.c
>> @@ -47,6 +47,7 @@
>> #include "vdbeInt.h"
>> #include "tarantoolInt.h"
>> #include "box/session.h"
>> +#include "box/schema.h"
>> /*
>> * This routine is called after a single SQL statement has been
>> @@ -433,6 +434,32 @@ sqlite3DeleteColumnNames(sqlite3 * db, Table *
>> pTable)
>> }
>> }
>> +/* Return true if given column is part of primary key. */
>> +bool
>> +table_column_is_primkey(Table *table, uint32_t column)
> I do not like primkey word &&
> The name is a little confusing, because one can suppose that the
> function checks if column is a primary key, while it actually checks
> if pk contains the column.
>
> I would like the name to be `is_column_in_pk` or something like this
>> +{
>> + uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(table->tnum);
>> + struct space *space = space_by_id(space_id);
>> + assert(space != NULL);
>> +
>> + struct index *primary_idx = index_find(space, 0 /* PK */);
>> + /* Views don't have any indexes. */
>> + if (primary_idx == NULL)
>> + return false;
>> + struct index_def *idx_def = primary_idx->def;
>> + uint64_t pk_mask = idx_def->key_def->column_mask;
>> + if (column < 63) {
> Are there any constants in Tarantool for this purpose? (63)
>> + return pk_mask & (1UL << column);
>> + } else if ((pk_mask & (1UL << 1)) != 0) {
> magic
>> + for (uint32_t i = 0; i < idx_def->key_def->part_count; ++i) {
>> + struct key_part *part = &idx_def->key_def->parts[i];
>> + if (part->fieldno == column)
>> + return true;
>> + }
>> + }
>> + return false;
>> +}
>> +
>> /*
>> * Remove the memory data structures associated with the given
>> * Table. No changes are made to disk by this routine.
>> @@ -1040,7 +1067,7 @@ sqlite3AddPrimaryKey(Parse * pParse, /*
>> Parsing context */
>> if (pList == 0) {
>> iCol = pTab->nCol - 1;
>> pCol = &pTab->aCol[iCol];
>> - pCol->colFlags |= COLFLAG_PRIMKEY;
>> + pCol->is_primkey = 1;
>> nTerm = 1;
>> } else {
>> nTerm = pList->nExpr;
>> @@ -1058,8 +1085,7 @@ sqlite3AddPrimaryKey(Parse * pParse, /*
>> Parsing context */
>> (zCName,
>> pTab->aCol[iCol].zName) == 0) {
>> pCol = &pTab->aCol[iCol];
>> - pCol->colFlags |=
>> - COLFLAG_PRIMKEY;
>> + pCol->is_primkey = 1;
>> break;
>> }
>> }
>> @@ -1423,7 +1449,7 @@ convertToWithoutRowidTable(Parse * pParse,
>> Table * pTab)
>> */
>> if (!db->init.imposterTable) {
>> for (i = 0; i < pTab->nCol; i++) {
>> - if ((pTab->aCol[i].colFlags & COLFLAG_PRIMKEY) != 0) {
>> + if (pTab->aCol[i].is_primkey) {
>> pTab->aCol[i].notNull = OE_Abort;
>> }
>> }
>> diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c
>> index d803a0df9..75930ebda 100644
>> --- a/src/box/sql/fkey.c
>> +++ b/src/box/sql/fkey.c
>> @@ -865,7 +865,7 @@ fkParentIsModified(Table * pTab, FKey * p, int
>> *aChange)
>> if (0 ==
>> strcmp(pCol->zName, zKey))
>> return 1;
>> - } else if (pCol->colFlags & COLFLAG_PRIMKEY) {
>> + } else if (table_column_is_primkey(pTab, iKey)) {
>> return 1;
>> }
>> }
>> diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
>> index 4aa3b2961..2b5cca435 100644
>> --- a/src/box/sql/pragma.c
>> +++ b/src/box/sql/pragma.c
>> @@ -352,8 +352,7 @@ sqlite3Pragma(Parse * pParse, Token * pId, /*
>> First part of [schema.]id field */
>> sqlite3ViewGetColumnNames(pParse, pTab);
>> for (i = 0, pCol = pTab->aCol; i < pTab->nCol;
>> i++, pCol++) {
>> - if ((pCol->
>> - colFlags & COLFLAG_PRIMKEY) == 0) {
>> + if (!table_column_is_primkey(pTab, i)) {
>> k = 0;
>> } else if (pPk == 0) {
>> k = 1;
>> diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
>> index 5fc612dea..fd732fa9e 100644
>> --- a/src/box/sql/sqliteInt.h
>> +++ b/src/box/sql/sqliteInt.h
>> @@ -1354,13 +1354,9 @@ struct Column {
>> u8 notNull; /* An OE_ code for handling a NOT NULL
>> constraint */
>> char affinity; /* One of the SQLITE_AFF_... values */
>> u8 szEst; /* Estimated size of value in this column.
>> sizeof(INT)==1 */
>> - u8 colFlags; /* Boolean properties. See COLFLAG_ defines
>> below */
>> + u8 is_primkey; /* Boolean propertie for being PK */
>> };
>> -/* Allowed values for Column.colFlags:
>> - */
>> -#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary
>> key */
>> -
>> /*
>> * A sort order can be either ASC or DESC.
>> */
>> @@ -3100,6 +3096,7 @@ void sqlite3ResetAllSchemasOfConnection(sqlite3
>> *);
>> void sqlite3ResetOneSchema(sqlite3 *);
>> void sqlite3CommitInternalChanges();
>> void sqlite3DeleteColumnNames(sqlite3 *, Table *);
>> +bool table_column_is_primkey(Table *, uint32_t);
>> int sqlite3ColumnsFromExprList(Parse *, ExprList *, i16 *, Column **);
>> void sqlite3SelectAddColumnTypeAndCollation(Parse *, Table *,
>> Select *);
>> Table *sqlite3ResultSetOfSelect(Parse *, Select *);
>> diff --git a/src/box/sql/update.c b/src/box/sql/update.c
>> index 8d0fe73ff..114f3c350 100644
>> --- a/src/box/sql/update.c
>> +++ b/src/box/sql/update.c
>> @@ -232,12 +232,9 @@ sqlite3Update(Parse * pParse, /* The
>> parser context */
>> goto update_cleanup;
>> }
>> for (j = 0; j < pTab->nCol; j++) {
>> - if (strcmp
>> - (pTab->aCol[j].zName, pChanges->a[i].zName) == 0) {
>> - if (pPk
>> - && (pTab->aCol[j].
>> - colFlags & COLFLAG_PRIMKEY) !=
>> - 0) {
>> + if (strcmp(pTab->aCol[j].zName,
>> + pChanges->a[i].zName) == 0) {
>> + if (pPk && table_column_is_primkey(pTab, j)) {
>> chngPk = 1;
>> }
>> aXRef[j] = i;
>> @@ -490,7 +487,7 @@ sqlite3Update(Parse * pParse, /* The
>> parser context */
>> for (i = 0; i < pTab->nCol; i++) {
>> if (oldmask == 0xffffffff
>> || (i < 32 && (oldmask & MASKBIT32(i)) != 0)
>> - || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY) != 0) {
>> + || table_column_is_primkey(pTab, i)) {
>> testcase(oldmask != 0xffffffff && i == 31);
>> sqlite3ExprCodeGetColumnOfTable(v, pTab,
>> iDataCur, i,
>
More information about the Tarantool-patches
mailing list