From ffe97075d3a4582abb8695a8fb3c7ca4f00c8716 Mon Sep 17 00:00:00 2001 From: Piotr Sarna Date: Thu, 27 Oct 2022 20:10:39 +0200 Subject: [PATCH] wip: add RANDOM ROWID table option With the new RANDOM ROWID keywords, a table can explicitly state that it wants its rowid to be generated randomly, not consecutively, without having to previously create a sentinel record with rowid == max(i64). Fixes #12 --- src/build.c | 4 ++++ src/insert.c | 4 ++++ src/parse.y | 10 +++++++++- src/sqliteInt.h | 2 ++ src/vdbe.c | 6 ++++++ tool/mkkeywordhash.c | 1 + 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/build.c b/src/build.c index be6b01eb08..b883322f6b 100644 --- a/src/build.c +++ b/src/build.c @@ -2708,6 +2708,10 @@ void sqlite3EndTable( p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; convertToWithoutRowidTable(pParse, p); } + if( tabOpts & TF_RandomRowid ){ + assert( (p->tabFlags & TF_WithoutRowid) == 0 ); + p->tabFlags |= TF_RandomRowid; + } iDb = sqlite3SchemaToIndex(db, p->pSchema); #ifndef SQLITE_OMIT_CHECK diff --git a/src/insert.c b/src/insert.c index 6c71391a1b..d4a93d963c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -818,6 +818,10 @@ void sqlite3Insert( ** sqlite_sequence table and store it in memory cell regAutoinc. */ regAutoinc = autoIncBegin(pParse, iDb, pTab); + if (pTab->tabFlags & TF_RandomRowid) { + fprintf(stderr, "Random rowid table detected: %s\n", pTab->zName); + regAutoinc = 0xffffffff; // libSQL + } /* Allocate a block registers to hold the rowid and the values ** for all columns of the new row. diff --git a/src/parse.y b/src/parse.y index d627f22ba2..badd2c3a89 100644 --- a/src/parse.y +++ b/src/parse.y @@ -216,6 +216,14 @@ table_option(A) ::= WITHOUT nm(X). { sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z); } } +table_option(A) ::= RANDOM nm(X). { + if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){ + A = TF_RandomRowid; + }else{ + A = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z); + } +} table_option(A) ::= nm(X). { if( X.n==6 && sqlite3_strnicmp(X.z,"strict",6)==0 ){ A = TF_Strict; @@ -248,7 +256,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);} CONFLICT DATABASE DEFERRED DESC DETACH DO EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN - QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS + QUERY KEY OF OFFSET PRAGMA RAISE RANDOM RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT NULLS FIRST LAST %ifdef SQLITE_OMIT_COMPOUND_SELECT diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6f1109f2f6..e33168612d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2341,6 +2341,8 @@ struct Table { #define TF_Ephemeral 0x00004000 /* An ephemeral table */ #define TF_Eponymous 0x00008000 /* An eponymous virtual table */ #define TF_Strict 0x00010000 /* STRICT mode */ +/* libSQL extension */ +#define TF_RandomRowid 0x01000000 /* Random rowid */ /* ** Allowed values for Table.eTabType diff --git a/src/vdbe.c b/src/vdbe.c index 4eb1c03271..beab551837 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5419,6 +5419,12 @@ case OP_NewRowid: { /* out2 */ } } + if ( pOp->p3 == 0xffffffff) { + fprintf(stderr, "assigning random rowid\n"); + pC->useRandomRowid = 1; + pOp->p3 = 0; + } + #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ /* Assert that P3 is a valid memory cell. */ diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index fe25b5abc0..481c4a1a87 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -278,6 +278,7 @@ static Keyword aKeywordTable[] = { { "PRIMARY", "TK_PRIMARY", ALWAYS, 1 }, { "QUERY", "TK_QUERY", EXPLAIN, 0 }, { "RAISE", "TK_RAISE", TRIGGER, 1 }, + { "RANDOM", "TK_RANDOM", ALWAYS, 1 }, { "RANGE", "TK_RANGE", WINDOWFUNC, 3 }, { "RECURSIVE", "TK_RECURSIVE", CTE, 3 }, { "REFERENCES", "TK_REFERENCES", FKEY, 1 },