]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Release some restrictions on columns added by ALTER TABLE so that they
authordrh <drh@noemail.net>
Fri, 8 May 2020 19:02:21 +0000 (19:02 +0000)
committerdrh <drh@noemail.net>
Fri, 8 May 2020 19:02:21 +0000 (19:02 +0000)
only apply if the table contains one or more rows.

FossilOrigin-Name: 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff

manifest
manifest.uuid
src/alter.c
src/build.c
src/expr.c
test/alter.test
test/alter3.test
test/alter4.test
test/fkey2.test
test/without_rowid3.test

index f775a4fca0e37efc023c010f51e71de3cedca9e2..07b0207e1c83ed360c0a05d141919ba23c4951fe 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\scount-optimization\sso\sthat\sit\shonors\sthe\sNOT\sINDEXED\sclause.
-D 2020-05-08T18:22:00.148
+C Release\ssome\srestrictions\son\scolumns\sadded\sby\sALTER\sTABLE\sso\sthat\sthey\nonly\sapply\sif\sthe\stable\scontains\sone\sor\smore\srows.
+D 2020-05-08T19:02:21.347
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -467,7 +467,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c fa2c3be9b0ebecfafb7062072a0ae6eda126d3e5a9fd51b2eded5acd95dc783c
+F src/alter.c 8d8e0b512a684596b3cf7026a92328575be5cefc7d0163e27a1fd179ad484512
 F src/analyze.c 953a6c43870ccaf080597244e1eeb4dc2ff6cb84f9501b24e46323de36970b61
 F src/attach.c ff2daea0fe62080192e3f262670e4f61f5a86c1e7bea9cec34e960fe79852aa1
 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
@@ -477,7 +477,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c f14e415fcfd0b52b4e4ebd193ba5fadac5e8252c30f023389af682813af44025
 F src/btree.h 989ef3c33413549e3e148f3dcb46c030f317dac130dc86809ba6b9aa4b16c72a
 F src/btreeInt.h 5c8b8749805787313ecf49eb5be3ced1e94bbf8ef54bb01470ce6bd0d5185c67
-F src/build.c 5566b570435d3511a0fd57388c124491b1f74e59561f0c1679fabe74c4c54b7a
+F src/build.c 5d19ef52be003d02e072dfc2892d7e107d20caf9ca49506937563de5c8d91141
 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6
@@ -485,7 +485,7 @@ F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384
 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
 F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f
 F src/delete.c 88047c8e59878c920fce14582bc1dde4d81157d1ca5ffdf36c2907e6d41996c4
-F src/expr.c d1e1d42cbdec08bb867a1ab43a59b401d82ff2bc88bdcb4af20e479a5facb6d8
+F src/expr.c 2918cac044a96d534d2f51bd121e913afda57314b8c5b00eb6bc1cf8999a7dea
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
 F src/func.c f3dcdc0e95509864767c1f0991b19360f969e44177f4e058fd51da9a6154f47e
@@ -632,10 +632,10 @@ F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54
 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
-F test/alter.test 77f0092d137dd9470fc683b64ed92868e188462e713e52f48deae8902ea60b96
+F test/alter.test 25e109787dc5e631e117eb6e1c57f96a572bb51228db3b4f8b5f41d665e2ccaa
 F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687
-F test/alter3.test 9351a9f0c59ff9dddecccaaa2f777ffee5369870c63d30d3a74add815254ec0f
-F test/alter4.test 74b22251c5e9c48093cfc4921ed9c11b59df84634aeeb00e501773320beb8424
+F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29
+F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf
 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499
 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf
@@ -875,7 +875,7 @@ F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f9339
 F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a
 F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
 F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768
-F test/fkey2.test 65c86b11127c11f80c0f450b3480321e0f087edea3031b9daa1978e3c020c91b
+F test/fkey2.test b1b6a8c5556dc0ccf31291b1fed8aa57e404b38f3236110e19ab4dc6aa93edf2
 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
 F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a
@@ -1751,7 +1751,7 @@ F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f1982
 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
 F test/without_rowid1.test 9cfb83705c506e3849fa7efc88a3c9a15f9a50bf9b1516b41757a7cef9bba8c3
 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
-F test/without_rowid3.test 392e6e12f275d11d931a8bc4580e573342f391639c87ffb631010a7b3cedfdc0
+F test/without_rowid3.test f8e6b9f7cb32a3570bab743dd4f28d2000e2107808d57585e776f5c3eb076241
 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
 F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
 F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e
@@ -1864,7 +1864,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 3fce9711a47329811cd333ae2f1d1384a96d73b9a5d6f9d08454a57a3fd24fc8
-R 8578e4a65d9ea9285aa73605ccc6eef5
+P 0d23a0b209900f4d7c6c13f75d4364f19afc23db72f9cfdb11e05b81502e8040
+R b78535f970f25edde428ed2df290db8d
 U drh
-Z e8a05b1abf68598bded8ccc3e45f3579
+Z 5bccd85159fe501fed38247765ad943e
index 12e90648832d0b5b9a6479b62d3977ed09477adc..b26a0cf61a91beb656d69351a4effcec39c22065 100644 (file)
@@ -1 +1 @@
-0d23a0b209900f4d7c6c13f75d4364f19afc23db72f9cfdb11e05b81502e8040
\ No newline at end of file
+3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff
\ No newline at end of file
index c357f220744fe7c303d0da0e077c1f3ab2fa99da..e5bac436a8b1a58c3db902898d9c4698238ecdc5 100644 (file)
@@ -255,6 +255,22 @@ exit_rename_table:
   db->mDbFlags = savedDbFlags;
 }
 
+/*
+** Write code that will raise an error if the table described by
+** zDb and zTab is not empty.
+*/
+static void sqlite3ErrorIfNotEmpty(
+  Parse *pParse,        /* Parsing context */
+  const char *zDb,      /* Schema holding the table */
+  const char *zTab,     /* Table to check for empty */
+  const char *zErr      /* Error message text */
+){
+  sqlite3NestedParse(pParse,
+     "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
+     zErr, zDb, zTab
+  );
+}
+
 /*
 ** This function is called after an "ALTER TABLE ... ADD" statement
 ** has been parsed. Argument pColDef contains the text of the new
@@ -307,7 +323,8 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
     return;
   }
   if( pNew->pIndex ){
-    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
+    sqlite3ErrorMsg(pParse,
+         "Cannot add a UNIQUE column");
     return;
   }
   if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
@@ -320,16 +337,15 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
       pDflt = 0;
     }
     if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
-      sqlite3ErrorMsg(pParse, 
+      sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
           "Cannot add a REFERENCES column with non-NULL default value");
-      return;
     }
     if( pCol->notNull && !pDflt ){
-      sqlite3ErrorMsg(pParse, 
+      sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
           "Cannot add a NOT NULL column with default value NULL");
-      return;
     }
 
+
     /* Ensure the default expression is something that sqlite3ValueFromExpr()
     ** can handle (i.e. not CURRENT_TIME etc.)
     */
@@ -343,14 +359,13 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
         return;
       }
       if( !pVal ){
-        sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
-        return;
+        sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
+           "Cannot add a column with non-constant default");
       }
       sqlite3ValueFree(pVal);
     }
   }else if( pCol->colFlags & COLFLAG_STORED ){
-    sqlite3ErrorMsg(pParse, "cannot add a STORED column");
-    return;
+    sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
   }
 
 
index 0b47e8e774d39014f7be34e3595cb06afdfb67d5..571d2652e08e74c46b9ee849e5a487efae504e33 100644 (file)
@@ -4741,7 +4741,7 @@ void sqlite3HaltConstraint(
   u8 p5Errmsg       /* P5_ErrMsg type */
 ){
   Vdbe *v = sqlite3GetVdbe(pParse);
-  assert( (errCode&0xff)==SQLITE_CONSTRAINT );
+  assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
   if( onError==OE_Abort ){
     sqlite3MayAbort(pParse);
   }
index 23e00db2ee3d81ff6c4e9d36f204106c060373d9..528377c5d620bd457cb18fc191e1ce873043d629 100644 (file)
@@ -4482,7 +4482,7 @@ expr_code_doover:
            || pExpr->affExpr==OE_Fail
            || pExpr->affExpr==OE_Ignore
       );
-      if( !pParse->pTriggerTab ){
+      if( !pParse->pTriggerTab && !pParse->nested ){
         sqlite3ErrorMsg(pParse,
                        "RAISE() may only be used within a trigger-program");
         return 0;
@@ -4496,8 +4496,9 @@ expr_code_doover:
             v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
         VdbeCoverage(v);
       }else{
-        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
-                              pExpr->affExpr, pExpr->u.zToken, 0, 0);
+        sqlite3HaltConstraint(pParse,
+             pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
+             pExpr->affExpr, pExpr->u.zToken, 0, 0);
       }
 
       break;
index 0ec485ef81cc1a4f194e6df4c7d202d35e84af41..43d2a6d5ae71ee5a180e998b0c85e8deeeceae34 100644 (file)
@@ -840,6 +840,7 @@ do_test alter-13.3 {
 do_test alter-14.1 {
   catchsql {
     CREATE TABLE t3651(a UNIQUE);
+    INSERT INTO t3651 VALUES(5);
     ALTER TABLE t3651 ADD COLUMN b UNIQUE;
   }
 } {1 {Cannot add a UNIQUE column}}
index b16a7f305bc83cb27d7947ceb406ce08e77de084..30bc1cbba242b412201a966ed363956b81c15b6d 100644 (file)
@@ -116,6 +116,7 @@ do_test alter3-1.99 {
 do_test alter3-2.1 {
   execsql {
     CREATE TABLE t1(a, b);
+    INSERT INTO t1 VALUES(1,2);
   }
   catchsql {
     ALTER TABLE t1 ADD c PRIMARY KEY;
index 92f33e7a36f59a868afe69509ae98ebc6fb45e2e..3aca7df3383b78f0c94367b1032f6225e0a265ad 100644 (file)
@@ -123,6 +123,7 @@ do_test alter4-1.99 {
 do_test alter4-2.1 {
   execsql {
     CREATE TABLE temp.t1(a, b);
+    INSERT INTO t1 VALUES(1,2);
   }
   catchsql {
     ALTER TABLE t1 ADD c PRIMARY KEY;
@@ -397,6 +398,7 @@ do_test alter4-10.1 {
 reset_db
 do_execsql_test alter4-11.0 {
   CREATE TABLE t1(c INTEGER PRIMARY KEY, d);
+  INSERT INTO t1(c,d) VALUES(1,2);
   PRAGMA foreign_keys = on;
   ALTER TABLE t1 ADD COLUMN e;
 }
index e7fa7b6457287b3d93086fc173ec0f723138c154..015c43cbd37a4dafe04e00015cd7f322637c4949 100644 (file)
@@ -955,6 +955,7 @@ ifcapable altertable {
     execsql { 
       CREATE TABLE t1(a PRIMARY KEY);
       CREATE TABLE t2(a, b);
+      INSERT INTO t2 VALUES(1,2);
     }
     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
   } {0 {}}
@@ -1046,6 +1047,7 @@ ifcapable altertable {
     execsql { 
       CREATE TEMP TABLE t1(a PRIMARY KEY);
       CREATE TEMP TABLE t2(a, b);
+      INSERT INTO temp.t2 VALUES(1,2);
     }
     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
   } {0 {}}
@@ -1130,6 +1132,7 @@ ifcapable altertable {
       ATTACH ':memory:' AS aux;
       CREATE TABLE aux.t1(a PRIMARY KEY);
       CREATE TABLE aux.t2(a, b);
+      INSERT INTO aux.t2(a,b) VALUES(1,2);
     }
     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
   } {0 {}}
index 24ef2304de379f0ad95085ca09f4fe95759d366a..a9839e147e792b2a18a7e2ed9e49f464f9e7348d 100644 (file)
@@ -921,6 +921,7 @@ ifcapable altertable {
     execsql { 
       CREATE TABLE t1(a PRIMARY KEY) WITHOUT rowid;
       CREATE TABLE t2(a, b);
+      INSERT INTO t2(a,b) VALUES(1,2);
     }
     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
   } {0 {}}
@@ -1015,6 +1016,7 @@ ifcapable altertable {
     execsql { 
       CREATE TEMP TABLE t1(a PRIMARY KEY) WITHOUT rowid;
       CREATE TEMP TABLE t2(a, b);
+      INSERT INTO temp.t2(a,b) VALUES(1,2);
     }
     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
   } {0 {}}
@@ -1102,6 +1104,7 @@ ifcapable altertable {
       ATTACH ':memory:' AS aux;
       CREATE TABLE aux.t1(a PRIMARY KEY) WITHOUT rowid;
       CREATE TABLE aux.t2(a, b);
+      INSERT INTO aux.t2(a,b) VALUES(1,2);
     }
     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
   } {0 {}}