I am not sure what to do with this. In Postgresql these two commands workI don’t understand how that ticket is related to given issue. Again, problemThen:It seems to be out of the scope of the patch. Appropriate ticket:
CREATE TABLE t11 (s1 INT, a, constraint c1 UNIQUE(s1) on conflict replace,
PRIMARY KEY(s1));
In this case creation of unique constraint c1 is omitted, but no errors or
warnings are shown.
It is not a problem now, but when ALTER TABLE DROP CONSTRAINT is
implemented,
it will be possible to drop c1 constraint. Eventually, user would be
disappointed if tried to drop
this constraint but got an error.
https://github.com/tarantool/tarantool/issues/3498
lies in
silent absorption of unique constraint by primary index.
silently, no UNIQUE
constraint is created
and ALTER TABLE works silently and do nothing.
In MySQL both constraints
will be created with no warnings or errors. What do you propose to do?
diff --git a/src/box/sql/build.c b/src/box/sql/build.cWhy do we need to allocate 'part_count' part of memory? It does not seem
index d66777f73..d2fed97eb 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -2430,13 +2430,14 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex,
int memRootPage)
}
struct Index *
-sql_index_alloc(struct sqlite3 *db)
+sql_index_alloc(struct sqlite3 *db, uint32_t part_count)
{
/* Size of struct Index and aiRowLogEst. */
- int index_size = ROUND8(sizeof(struct Index));
+ int index_size = sizeof(struct Index) +
+ sizeof(LogEst) * (part_count + 1);
struct Index *p = sqlite3DbMallocZero(db, index_size);
if (p != NULL)
- p->aiRowLogEst = (LogEst *) ((char *)p + ROUND8(sizeof(*p)));
+ p->aiRowLogEst = (LogEst *) ((char *)p + sizeof(*p));
return p;
}
@@ -2769,11 +2757,10 @@ sql_create_index(struct Parse *parse, struct Token
*token,
if (sqlite3CheckIdentifierName(parse, name) != SQLITE_OK)
goto exit_create_index;
- index = sql_index_alloc(db);
+ index = sql_index_alloc(db, col_list->nExpr);
@@ -2769,11 +2757,10 @@ sql_create_index(struct Parse *parse, struct Token
*token,
if (sqlite3CheckIdentifierName(parse, name) != SQLITE_OK)
goto exit_create_index;
- index = sql_index_alloc(db);
+ index = sql_index_alloc(db, col_list->nExpr);
if (index == NULL)
goto exit_create_index;
- assert(EIGHT_BYTE_ALIGNMENT(index->aiRowLogEst));
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index ae31dfae5..2082d6ca9 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -3631,7 +3631,7 @@ void sqlite3SrcListDelete(sqlite3 *, SrcList *);
* @retval not NULL Index object.
*/
struct Index *
-sql_index_alloc(struct sqlite3 *db);
+sql_index_alloc(struct sqlite3 *db, uint32_t part_count);
to be used for anything.
Yes, it seems to be a better solution. What do you think about adding a fieldWell, if smb called index ‘fake_autoindex’, I guess strange things wouldRemoved with ‘fake_autoindex'diff --git a/src/box/sql/where.c b/src/box/sql/where.cWe are going to remove tnum from struct Index and struct Table.
index 85143ed20..7ca02095f 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -372,13 +372,19 @@ whereScanInit(WhereScan * pScan, /* The
WhereScan object being initialized */
pScan->is_column_seen = false;
if (pIdx) {
int j = iColumn;
- iColumn = pIdx->aiColumn[j];
+ iColumn = pIdx->def->key_def->parts[j].fieldno;
+ /*
+ * pIdx->tnum == 0 means that pIdx is a fake
+ * integer primary key index.
+ */
+ if (pIdx->tnum == 0)
+ iColumn = -1;
So, if it is possible, use index->def->iid instead (or smth else).
happen.
Could we use for instance def->space_id == 0 as a sign of ‘fake_index'?.
to
index_def.opts - index_def.opts.is_fake_pk?
In index_def_new() (where we pass opts) given sql_stmt is copied using
Moreover, sql_stmt is obtained from sqlite3Malloc() and assigned to
index->opts,
which in turn is released by common free().
strdup, so
it's okay to free() it, isn't it?
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index d66777f73..0cb0b8e08 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -984,8 +984,10 @@ sqlite3AddPrimaryKey(Parse * pParse, /* Parsing
context */
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY or INT PRIMARY KEY");
} else {
+ /* Since this index implements PK, it is unique. */
sql_create_index(pParse, 0, 0, pList, onError, 0,
- 0, sortOrder, false,
SQLITE_IDXTYPE_PRIMARYKEY);
+ 0, sortOrder, false, SQLITE_IDXTYPE_PRIMARYKEY,
+ true);
pList = 0;
}
@@ -1311,9 +1313,10 @@ convertToWithoutRowidTable(Parse * pParse, Table *
pTab)
return;
pList->a[0].sort_order = pParse->iPkSortOrder;
assert(pParse->pNewTable == pTab);
+ /* Since this index implements PK, it is unique. */
sql_create_index(pParse, 0, 0, pList, pTab->keyConf, 0, 0,
SORT_ORDER_ASC, false,
- SQLITE_IDXTYPE_PRIMARYKEY);
+ SQLITE_IDXTYPE_PRIMARYKEY, true);
if (db->mallocFailed)
return;
pPk = sqlite3PrimaryKeyIndex(pTab);
@@ -2538,10 +2541,8 @@ addIndexToTable(Index * pIndex, Table * pTab)
* @param expr_list List of expressions, describe which columns
* of 'table' are used in index and also their
* collations, orders, etc.
- * @param idx_type Index type, one of the following:
- * SQLITE_IDXTYPE_APPDEF 0
- * SQLITE_IDXTYPE_UNIQUE 1
- * SQLITE_IDXTYPE_PRIMARYKEY 2.
+ * @param idx_type Index type: UNIQUE constraint, PK constraint,
+ * or created by <CREATE INDEX ...> stmt.
* @param sql_stmt SQL statement, which creates the index.
* @retval 0 Success.
* @retval -1 Error.
@@ -2632,7 +2633,7 @@ sql_create_index(struct Parse *parse, struct Token
*token,
struct SrcList *tbl_name, struct ExprList *col_list,
enum on_conflict_action on_error, struct Token *start,
struct Expr *where, enum sort_order sort_order,
- bool if_not_exist, u8 idx_type)
+ bool if_not_exist, u8 idx_type, bool is_unique)