]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
ALTER TABLE is able to add a VIRTUAL column.
authordrh <drh@noemail.net>
Wed, 16 Oct 2019 20:05:56 +0000 (20:05 +0000)
committerdrh <drh@noemail.net>
Wed, 16 Oct 2019 20:05:56 +0000 (20:05 +0000)
FossilOrigin-Name: 120c6b78cb51532f783014605f1107d40b2e4f54e3852fb1f8f167d0c0b78c69

manifest
manifest.uuid
src/alter.c
src/build.c
src/insert.c
src/sqliteInt.h

index f1dc653477a8d5acb72033fcdccfec59162b0001..991a0bbbfff160ec59f00d1c6ab72efaa3f40fb6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Simple\sINSERT\sand\sSELECT\soperations\sworking\swith\sVIRTUAL\scolumns.
-D 2019-10-16T19:31:46.693
+C ALTER\sTABLE\sis\sable\sto\sadd\sa\sVIRTUAL\scolumn.
+D 2019-10-16T20:05:56.905
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -459,7 +459,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c 5773b28684a001dcab45adcefa3cbf5e846335c0c8fee0da8a3770cb0123bba8
+F src/alter.c 8a4317e2b322d4da9489cf2aa1d513a3a6f3e4863552dd5e59d08cdaca73c487
 F src/analyze.c 481d9cf34a3c70631ef5c416be70033e8d4cd85eb5ad1b37286aed8b0e29e889
 F src/attach.c 3ca19504849c2d9be10fc5899d6811f9d6e848665d1a41ffb53df0cd6e7c13ed
 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
@@ -469,7 +469,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c a8a9c2ce62bdf54c8cf9795143d7cb10b7473a1230a0572f702d061ffcceefe5
 F src/btree.h f27a33c49280209a93385e218306c4ee5f46ba8d7649d2f81a7166b282232484
 F src/btreeInt.h 91806f01fd1145a9a86ba3042f25c38d8faf6002701bf5e780742cf88bcff437
-F src/build.c 0ed5a7bb102a1972ce045b7a14753ed65bf62c7e32a44f162bfdce6f50bd7619
+F src/build.c 6cb40a36b3ec6a4b2dc36e0bd53e42ad448700c48b419569eae711cde4b175d3
 F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
@@ -486,7 +486,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c de9dea8081c500156d8c2e0079a123d56ef736d283ec7806f401886dd55c5ab7
+F src/insert.c c54ef99a0c47788a3cf2ace9ef9717b137484569e4c04bd940fc5222a6b3c209
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d
 F src/main.c 3e01f6a1c96643381b5f9d79e4ff7f2520bc5712197746fb0852283e78cccf66
@@ -530,7 +530,7 @@ F src/shell.c.in d70bcf630c4073eaa994fa74be98886c781918e794cb8b562be8df10f018e27
 F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
-F src/sqliteInt.h 47d43085f2165aa4ddb87f8a0341937104dfd94bcce0445d296eac8e59ab25e2
+F src/sqliteInt.h 6418b27039289b0274077c0f4f54b82c3150881b64dddb7d128786b55ec09920
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1847,7 +1847,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 11d472c1df707b8d03ec57d8fc582a34f5eb89a9d02a154a9871650c65065b45
-R 899dceb15c24c2e2f3f3f41aea0d96fa
+P 7f9f90b1b885fa9905b296f2e0fcc9b2341019b42fc839722a93cf60e49a9252
+R 8a88337d2c1f89903f9ecf943d42ac46
 U drh
-Z 2fd76d80cb2634f812acd88fb56b891f
+Z e34cdc64b33126ce9923adb3fcc6f90a
index 43616447f968281fd1e05c406212b0535e4e8c36..3dd4dbb53487700b65cfa86d02328cd22db25741 100644 (file)
@@ -1 +1 @@
-7f9f90b1b885fa9905b296f2e0fcc9b2341019b42fc839722a93cf60e49a9252
\ No newline at end of file
+120c6b78cb51532f783014605f1107d40b2e4f54e3852fb1f8f167d0c0b78c69
\ No newline at end of file
index 9d02d3835a91728a31c523e3c64eb9fbea878cd5..f8cada0e34d391f09c180eca4bfe0882129f24b4 100644 (file)
@@ -298,14 +298,6 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
   }
 #endif
 
-  /* If the default value for the new column was specified with a 
-  ** literal NULL, then set pDflt to 0. This simplifies checking
-  ** for an SQL NULL default below.
-  */
-  assert( pDflt==0 || pDflt->op==TK_SPAN );
-  if( pDflt && pDflt->pLeft->op==TK_NULL ){
-    pDflt = 0;
-  }
 
   /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
   ** If there is a NOT NULL constraint, then the default value for the
@@ -319,36 +311,47 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
     sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
     return;
   }
-  if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
-    sqlite3ErrorMsg(pParse, 
-        "Cannot add a REFERENCES column with non-NULL default value");
-    return;
-  }
-  if( pCol->notNull && !pDflt ){
-    sqlite3ErrorMsg(pParse, 
-        "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.)
-  */
-  if( pDflt ){
-    sqlite3_value *pVal = 0;
-    int rc;
-    rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
-    assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
-    if( rc!=SQLITE_OK ){
-      assert( db->mallocFailed == 1 );
+  if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
+    /* If the default value for the new column was specified with a 
+    ** literal NULL, then set pDflt to 0. This simplifies checking
+    ** for an SQL NULL default below.
+    */
+    assert( pDflt==0 || pDflt->op==TK_SPAN );
+    if( pDflt && pDflt->pLeft->op==TK_NULL ){
+      pDflt = 0;
+    }
+    if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
+      sqlite3ErrorMsg(pParse, 
+          "Cannot add a REFERENCES column with non-NULL default value");
       return;
     }
-    if( !pVal ){
-      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
+    if( pCol->notNull && !pDflt ){
+      sqlite3ErrorMsg(pParse, 
+          "Cannot add a NOT NULL column with default value NULL");
       return;
     }
-    sqlite3ValueFree(pVal);
+
+    /* Ensure the default expression is something that sqlite3ValueFromExpr()
+    ** can handle (i.e. not CURRENT_TIME etc.)
+    */
+    if( pDflt ){
+      sqlite3_value *pVal = 0;
+      int rc;
+      rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
+      assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+      if( rc!=SQLITE_OK ){
+        assert( db->mallocFailed == 1 );
+        return;
+      }
+      if( !pVal ){
+        sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
+        return;
+      }
+      sqlite3ValueFree(pVal);
+    }
   }
 
+
   /* Modify the CREATE TABLE statement. */
   zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
   if( zCol ){
index 7e1f3b40cf567754cdd450df7132c93ee9c52f48..897e9183eb73a24937051a3704dfa273fe2ef9e6 100644 (file)
@@ -1570,7 +1570,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
   goto generated_done;
 
 generated_error:
-  sqlite3ErrorMsg(pParse, "bad GENERATED ALWAYS AS clause on column \"%s\"",
+  sqlite3ErrorMsg(pParse, "incorrect GENERATED ALWAYS AS on column \"%s\"",
                   pCol->zName);
 generated_done:
   sqlite3ExprDelete(pParse->db, pExpr);
index f2ed9d9a323f9d95acb1e7af6f061065fbd511f2..22c48d7f3c8af0489f0e2dacfb1be6430d132575 100644 (file)
@@ -532,6 +532,7 @@ void sqlite3Insert(
   u8 withoutRowid;      /* 0 for normal table.  1 for WITHOUT ROWID table */
   u8 bIdListInOrder;    /* True if IDLIST is in table order */
   ExprList *pList = 0;  /* List of VALUES() to be inserted  */
+  int iRegStore;        /* Register in which to store next column */
 
   /* Register allocations */
   int regFromSelect = 0;/* Base register for data coming from SELECT */
@@ -1003,8 +1004,8 @@ void sqlite3Insert(
     ** with the first column.
     */
     nHidden = 0;
-    for(i=0; i<pTab->nCol; i++){
-      int iRegStore = regRowid+1+i;
+    iRegStore = regRowid+1;
+    for(i=0; i<pTab->nCol; i++, iRegStore++){
       if( i==pTab->iPKey ){
         /* The value of the INTEGER PRIMARY KEY column is always a NULL.
         ** Whenever this column is read, the rowid will be substituted
@@ -1019,6 +1020,7 @@ void sqlite3Insert(
           j = -1;
           nHidden++;
           if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){
+            iRegStore--;
             continue;
           }
         }else{
index 94d7107a08289d6dacb9da7f134b2b288a649c8c..eb815a79e0eddfcf445eefd5d7141dc6fc31bf03 100644 (file)
@@ -1840,6 +1840,7 @@ struct Column {
 #define COLFLAG_SORTERREF 0x0010   /* Use sorter-refs with this column */
 #define COLFLAG_VIRTUAL   0x0020   /* GENERATED ALWAYS AS ... VIRTUAL */
 #define COLFLAG_STORED    0x0040   /* GENERATED ALWAYS AS ... STORED */
+#define COLFLAG_GENERATED 0x0060   /* Combo: _STORED, _VIRTUAL */
 #define COLFLAG_NOINSERT  0x0062   /* Combo: _HIDDEN, _STORED, _VIRTUAL */
 
 /*