From: drh Date: Wed, 16 Oct 2019 20:05:56 +0000 (+0000) Subject: ALTER TABLE is able to add a VIRTUAL column. X-Git-Tag: version-3.31.0~376^2~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c27ea2ae8df4207e6b2479b46904c73d7cd1775f;p=thirdparty%2Fsqlite.git ALTER TABLE is able to add a VIRTUAL column. FossilOrigin-Name: 120c6b78cb51532f783014605f1107d40b2e4f54e3852fb1f8f167d0c0b78c69 --- diff --git a/manifest b/manifest index f1dc653477..991a0bbbff 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 43616447f9..3dd4dbb534 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f9f90b1b885fa9905b296f2e0fcc9b2341019b42fc839722a93cf60e49a9252 \ No newline at end of file +120c6b78cb51532f783014605f1107d40b2e4f54e3852fb1f8f167d0c0b78c69 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 9d02d3835a..f8cada0e34 100644 --- a/src/alter.c +++ b/src/alter.c @@ -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 ){ diff --git a/src/build.c b/src/build.c index 7e1f3b40cf..897e9183eb 100644 --- a/src/build.c +++ b/src/build.c @@ -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); diff --git a/src/insert.c b/src/insert.c index f2ed9d9a32..22c48d7f3c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -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; inCol; i++){ - int iRegStore = regRowid+1+i; + iRegStore = regRowid+1; + for(i=0; inCol; 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{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 94d7107a08..eb815a79e0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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 */ /*