-C Improved\sheader\scomment\swith\sbetter\sinstructions\son\sthe\svfslog.c\nextension.
-D 2013-10-19T16:51:39.506
+C Experimental\schanges\stoward\s"index\sonly"\stables.\s\sAdd\sthe\sability\sto\sspecify\noptions\son\sCREATE\sTABLE\sstatements\susing\sthe\sWITH\sclause\smodeled\safter\nPostgreSQL\sand\sSQL\sServer.\s\sOnly\sthe\s"omit_rowid"\soption\sis\scurrently\nrecognized\sand\sthat\soption\sis\scurrently\sa\sno-op.
+D 2013-10-19T23:31:56.588
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/btree.c 509722ce305471b626d3401c0631a808fd33237b
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c 6d9a545d726956fdc0c63d7076291fc9e7207484
+F src/build.c 2adfe99b972f1f270e602c39f7c726fa8477343b
F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
F src/os_win.c b159b5249d9f70607d961bbdd1dbba789c75812c
F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8
F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
-F src/parse.y a97566d6da75075589a7c716d1bda14b586cf8da
+F src/parse.y 909868a9a60caeaa94d439a8b321e5491f989111
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
F src/sqlite.h.in 547a44dd4ff4d975e92a645ea2d609e543a83d0f
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 4dd81a25a919509ce94b1f8f120bbef14458d4b9
+F src/sqliteInt.h 64409173b3e74ae26c66e737fa36d0b792dd77f9
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
-F test/alter.test 775a1dded3f8247983c9a3e767b011d9a5114442
+F test/alter.test f128974fbafff7c57e9f5ff2b2ecdd1dd4c4f84d
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
F test/alter4.test 8e93bf7a7e6919b14b0c9a6c1e4908bcf21b0165
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/table.test 30423211108121884588d24d6776c7f38702ad7b
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
+F test/tableopts.test 28c869c5590fac5469a6da0a3612485d8c64cd25
F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
-F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79
+F tool/mkkeywordhash.c d29369d17069558affef8c4ed5c58ad6c0238c68
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 3fc52e00a234750675e8a569d2919ff48558e9eb
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 56dca4a65c3b14123272fa0cc5c15530c06fda28
-R 1cee309be53ed4b90f763a6791fd81dc
+P 4bd592c8f0e011e203443a6e88008a61d6926df5
+R fbf9e989e7ae142368f9794120af33f8
+T *branch * omit-rowid
+T *sym-omit-rowid *
+T -sym-trunk *
U drh
-Z 23f623447e2329bbecfcb9fee8496fa4
+Z 7440405d7d57d4e7a838139e7bed4bdc
-4bd592c8f0e011e203443a6e88008a61d6926df5
\ No newline at end of file
+0248ec5e6e3797575388f046d8c27f7445fe2a39
\ No newline at end of file
void sqlite3EndTable(
Parse *pParse, /* Parse context */
Token *pCons, /* The ',' token after the last column defn. */
- Token *pEnd, /* The final ')' token in the CREATE TABLE */
+ Token *pEnd1, /* The ')' before options in the CREATE TABLE */
+ Token *pEnd2, /* The final ')' in the whole CREATE TABLE */
+ IdList *pOpts, /* List of table options. May be NULL */
Select *pSelect /* Select from a "CREATE ... AS SELECT" */
){
Table *p; /* The new table */
int iDb; /* Database in which the table lives */
Index *pIdx; /* An implied index of the table */
- if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
- return;
+ if( (pEnd1==0 && pSelect==0) || db->mallocFailed ){
+ goto end_table_exception;
}
p = pParse->pNewTable;
- if( p==0 ) return;
+ if( p==0 ) goto end_table_exception;
assert( !db->init.busy || !pSelect );
+ if( pOpts ){
+ int i;
+ for(i=0; i<pOpts->nId; i++){
+ if( sqlite3_stricmp(pOpts->a[i].zName, "omit_rowid")==0 ){
+ p->tabFlags |= TF_WithoutRowid;
+ if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
+ sqlite3ErrorMsg(pParse, "no PRIMARY KEY for table %s", p->zName);
+ }
+ continue;
+ }
+ sqlite3ErrorMsg(pParse, "unknown table option: %s", pOpts->a[i].zName);
+ }
+ }
+
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
+ if( NEVER(v==0) ) goto end_table_exception;
sqlite3VdbeAddOp1(v, OP_Close, 0);
sqlite3VdbeAddOp1(v, OP_Close, 1);
if( pParse->nErr==0 ){
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
- if( pSelTab==0 ) return;
+ if( pSelTab==0 ) goto end_table_exception;
assert( p->aCol==0 );
p->nCol = pSelTab->nCol;
p->aCol = pSelTab->aCol;
if( pSelect ){
zStmt = createTableStmt(db, p);
}else{
- n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
+ n = (int)(pEnd2->z - pParse->sNameToken.z) + 1;
zStmt = sqlite3MPrintf(db,
"CREATE %s %.*s", zType2, n, pParse->sNameToken.z
);
if( pOld ){
assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
db->mallocFailed = 1;
- return;
+ goto end_table_exception;
}
pParse->pNewTable = 0;
db->flags |= SQLITE_InternChanges;
if( !p->pSelect ){
const char *zName = (const char *)pParse->sNameToken.z;
int nName;
- assert( !pSelect && pCons && pEnd );
+ assert( !pSelect && pCons && pEnd1 );
if( pCons->z==0 ){
- pCons = pEnd;
+ pCons = pEnd1;
}
nName = (int)((const char *)pCons->z - zName);
p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName);
}
#endif
}
+
+end_table_exception:
+ sqlite3IdListDelete(db, pOpts);
+ return;
}
#ifndef SQLITE_OMIT_VIEW
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
- sqlite3EndTable(pParse, 0, &sEnd, 0);
+ sqlite3EndTable(pParse, 0, &sEnd, &sEnd, 0, 0);
return;
}
#endif /* SQLITE_OMIT_VIEW */
temp(A) ::= TEMP. {A = 1;}
%endif SQLITE_OMIT_TEMPDB
temp(A) ::= . {A = 0;}
-create_table_args ::= LP columnlist conslist_opt(X) RP(Y). {
- sqlite3EndTable(pParse,&X,&Y,0);
+create_table_args ::= LP columnlist conslist_opt(X) RP(E1). {
+ sqlite3EndTable(pParse,&X,&E1,&E1,0,0);
+}
+create_table_args ::= LP columnlist conslist_opt(X) RP(E1)
+ WITH LP idlist(Z) RP(E2). {
+ sqlite3EndTable(pParse,&X,&E1,&E2,Z,0);
}
create_table_args ::= AS select(S). {
- sqlite3EndTable(pParse,0,0,S);
+ sqlite3EndTable(pParse,0,0,0,0,S);
sqlite3SelectDelete(pParse->db, S);
}
columnlist ::= columnlist COMMA column.
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RELEASE REPLACE RESTRICT ROW ROLLBACK
- SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL
+ SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
%type using_opt {IdList*}
%destructor using_opt {sqlite3IdListDelete(pParse->db, $$);}
-using_opt(U) ::= USING LP inscollist(L) RP. {U = L;}
+using_opt(U) ::= USING LP idlist(L) RP. {U = L;}
using_opt(U) ::= . {U = 0;}
%type inscollist_opt {IdList*}
%destructor inscollist_opt {sqlite3IdListDelete(pParse->db, $$);}
-%type inscollist {IdList*}
-%destructor inscollist {sqlite3IdListDelete(pParse->db, $$);}
+%type idlist {IdList*}
+%destructor idlist {sqlite3IdListDelete(pParse->db, $$);}
inscollist_opt(A) ::= . {A = 0;}
-inscollist_opt(A) ::= LP inscollist(X) RP. {A = X;}
-inscollist(A) ::= inscollist(X) COMMA nm(Y).
+inscollist_opt(A) ::= LP idlist(X) RP. {A = X;}
+idlist(A) ::= idlist(X) COMMA nm(Y).
{A = sqlite3IdListAppend(pParse->db,X,&Y);}
-inscollist(A) ::= nm(Y).
+idlist(A) ::= nm(Y).
{A = sqlite3IdListAppend(pParse->db,0,&Y);}
/////////////////////////// Expression Processing /////////////////////////////
%destructor trigger_event {sqlite3IdListDelete(pParse->db, $$.b);}
trigger_event(A) ::= DELETE|INSERT(OP). {A.a = @OP; A.b = 0;}
trigger_event(A) ::= UPDATE(OP). {A.a = @OP; A.b = 0;}
-trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X;}
+trigger_event(A) ::= UPDATE OF idlist(X). {A.a = TK_UPDATE; A.b = X;}
foreach_clause ::= .
foreach_clause ::= FOR EACH ROW.
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
+#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
/*
void sqlite3AddColumnType(Parse*,Token*);
void sqlite3AddDefaultValue(Parse*,ExprSpan*);
void sqlite3AddCollateType(Parse*, Token*);
-void sqlite3EndTable(Parse*,Token*,Token*,Select*);
+void sqlite3EndTable(Parse*,Token*,Token*,Token*,IdList*,Select*);
int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
} [list 1 "table $tbl may not be altered"]
}
+#------------------------------------------------------------------------
+# Verify that ALTER TABLE works on tables with WITH options.
+#
+do_execsql_test alter-16.1 {
+ CREATE TABLE t16a(a TEXT, b REAL, c INT, PRIMARY KEY(a,b)) WITH (omit_rowid);
+ INSERT INTO t16a VALUES('abc',1.25,99);
+ ALTER TABLE t16a ADD COLUMN d TEXT DEFAULT 'xyzzy';
+ INSERT INTO t16a VALUES('cba',5.5,98,'fizzle');
+ SELECT * FROM t16a ORDER BY a;
+} {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
+do_execsql_test alter-16.2 {
+ ALTER TABLE t16a RENAME TO t16a_rn;
+ SELECT * FROM t16a_rn ORDER BY a;
+} {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
finish_test
--- /dev/null
+# 2013-10-19
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# Test the operation of table-options in the WITH clause of the
+# CREATE TABLE statement.
+#
+
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_test tableopt-1.1 {
+ catchsql {
+ CREATE TABLE t1(a,b) WITH (omit_rowid);
+ }
+} {1 {no PRIMARY KEY for table t1}}
+do_test tableopt-1.2 {
+ catchsql {
+ CREATE TABLE t1(a,b) WITH (unknown1, unknown2);
+ }
+} {1 {unknown table option: unknown2}}
+do_test tableopt-1.3 {
+ catchsql {
+ CREATE TABLE t1(a,b,c,PRIMARY KEY(a,b)) WITH (omit_rowid, unknown3);
+ }
+} {1 {unknown table option: unknown3}}
+do_test tableopt-1.4 {
+ catchsql {
+ CREATE TABLE t1(a,b,c,PRIMARY KEY(a,b)) WITH (unknown4, omit_rowid);
+ }
+} {1 {unknown table option: unknown4}}
+
+do_execsql_test tableopt-2.1 {
+ CREATE TABLE t1(a, b, c, PRIMARY KEY(a,b)) WITH (omit_rowid);
+ INSERT INTO t1 VALUES(1,2,3),(2,3,4);
+ SELECT c FROM t1 WHERE a IN (1,2) ORDER BY b;
+} {3 4}
+do_execsql_test tableopt-2.2 {
+ VACUUM;
+ SELECT c FROM t1 WHERE a IN (1,2) ORDER BY b;
+} {3 4}
+do_test tableopt-2.3 {
+ sqlite3 db2 test.db
+ db2 eval {SELECT c FROM t1 WHERE a IN (1,2) ORDER BY b;}
+} {3 4}
+db2 close
+
+finish_test
{ "VALUES", "TK_VALUES", ALWAYS },
{ "VIEW", "TK_VIEW", VIEW },
{ "VIRTUAL", "TK_VIRTUAL", VTAB },
+ { "WITH", "TK_WITH", ALWAYS },
{ "WHEN", "TK_WHEN", ALWAYS },
{ "WHERE", "TK_WHERE", ALWAYS },
};