Skip to content

Commit

Permalink
sql: move autoincrement in vdbe
Browse files Browse the repository at this point in the history
This patch expands changes made in issue #2981. Now NULL
in primary key always replaced by generated value inside
of vdbe. It allows us to get last_insert_id with easy.

Part of ...
  • Loading branch information
ImeevMA committed Sep 13, 2018
1 parent 47969ef commit 6f641eb
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
13 changes: 9 additions & 4 deletions src/box/sql/insert.c
Expand Up @@ -656,9 +656,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */
if (j < 0 || nColumn == 0
|| (pColumn && j >= pColumn->nId)) {
if (i == (int) autoinc_fieldno) {
sqlite3VdbeAddOp2(v,
OP_NextAutoincValue,
pTab->def->id,
sqlite3VdbeAddOp2(v, OP_Null, 0,
iRegStore);
continue;
}
Expand Down Expand Up @@ -739,7 +737,14 @@ sqlite3Insert(Parse * pParse, /* Parser context */
iRegStore);
}
}

/*
* Replace NULL in PK with autoincrement by
* generated value.
*/
if ((int) autoinc_fieldno >= 0) {
sqlite3VdbeAddOp2(v, OP_NextAutoincValue, pTab->def->id,
regData + (int) autoinc_fieldno);
}
/*
* Generate code to check constraints and process
* final insertion.
Expand Down
6 changes: 5 additions & 1 deletion src/box/sql/vdbe.c
Expand Up @@ -1157,6 +1157,10 @@ case OP_NextAutoincValue: {
assert(pOp->p1 > 0);
assert(pOp->p2 > 0);

pIn2 = &p->aMem[pOp->p2];
if ((pIn2->flags & MEM_Null) == 0)
break;

struct space *space = space_by_id(pOp->p1);
if (space == NULL) {
rc = SQL_TARANTOOL_ERROR;
Expand Down Expand Up @@ -3755,7 +3759,7 @@ case OP_FCopy: { /* out2 */

if ((pOp->p3 & OPFLAG_NOOP_IF_NULL) && (pIn1->flags & MEM_Null)) {
pOut = &aMem[pOp->p2];
if (pOut->flags & MEM_Undefined) pOut->flags = MEM_Null;
pOut->flags = MEM_Null;
/* Flag is set and register is NULL -> do nothing */
} else {
assert(memIsValid(pIn1));
Expand Down
13 changes: 13 additions & 0 deletions test/sql/gh-2981-check-autoinc.result
Expand Up @@ -19,6 +19,9 @@ box.sql.execute("CREATE TABLE t2 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEG
box.sql.execute("CREATE TABLE t3 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 < 10));");
---
...
box.sql.execute("CREATE TABLE t4 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19));");
---
...
box.sql.execute("insert into t1 values (18, null);")
---
...
Expand Down Expand Up @@ -47,6 +50,13 @@ box.sql.execute("insert into t3(s2) values (null)")
---
- error: 'CHECK constraint failed: T3'
...
box.sql.execute("insert into t4 values (18, null);")
---
...
box.sql.execute("insert into t4 values (null, null);")
---
- error: 'CHECK constraint failed: T4'
...
box.sql.execute("DROP TABLE t1")
---
...
Expand All @@ -56,3 +66,6 @@ box.sql.execute("DROP TABLE t2")
box.sql.execute("DROP TABLE t3")
---
...
box.sql.execute("DROP TABLE t4")
---
...
6 changes: 5 additions & 1 deletion test/sql/gh-2981-check-autoinc.test.lua
Expand Up @@ -7,6 +7,7 @@ box.cfg{}
box.sql.execute("CREATE TABLE t1 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19));");
box.sql.execute("CREATE TABLE t2 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19 AND s1 <> 25));");
box.sql.execute("CREATE TABLE t3 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 < 10));");
box.sql.execute("CREATE TABLE t4 (s1 INTEGER PRIMARY KEY AUTOINCREMENT, s2 INTEGER, CHECK (s1 <> 19));");

box.sql.execute("insert into t1 values (18, null);")
box.sql.execute("insert into t1(s2) values (null);")
Expand All @@ -19,7 +20,10 @@ box.sql.execute("insert into t2(s2) values (null);")
box.sql.execute("insert into t3 values (9, null)")
box.sql.execute("insert into t3(s2) values (null)")

box.sql.execute("insert into t4 values (18, null);")
box.sql.execute("insert into t4 values (null, null);")

box.sql.execute("DROP TABLE t1")
box.sql.execute("DROP TABLE t2")
box.sql.execute("DROP TABLE t3")

box.sql.execute("DROP TABLE t4")

0 comments on commit 6f641eb

Please sign in to comment.