]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Refactor the way that DEFAULT expressions are stored on columns, in order
authordrh <>
Sat, 31 Jul 2021 20:30:41 +0000 (20:30 +0000)
committerdrh <>
Sat, 31 Jul 2021 20:30:41 +0000 (20:30 +0000)
to save memory in the common case where the column has no DEFAULT clause.

FossilOrigin-Name: 8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a

manifest
manifest.uuid
src/alter.c
src/build.c
src/expr.c
src/fkey.c
src/insert.c
src/pragma.c
src/sqliteInt.h
src/update.c
src/vtab.c

index e3ec8ecc4f781bebd075896bfb7d9c24e5047e56..e1878e788bed8712a1316ecf3540979ac855dcc3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Recognize\scertain\sstandard\sdatatypes\s("INT",\s"INTEGER",\s"REAL",\s"TEXT",\sand\n"BLOB")\sand\sif\sa\scolumn\shas\sone\sof\sthose\sdatatypes,\sstore\sthe\stype\spart\sof\nthe\sbit-field\sinformation\sin\sthe\sColumn\sstructure\sto\ssave\sspace.
-D 2021-07-30T23:30:30.921
+C Refactor\sthe\sway\sthat\sDEFAULT\sexpressions\sare\sstored\son\scolumns,\sin\sorder\nto\ssave\smemory\sin\sthe\scommon\scase\swhere\sthe\scolumn\shas\sno\sDEFAULT\sclause.
+D 2021-07-31T20:30:41.189
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -478,7 +478,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c a54e0a5ae778271a0bc67bdb590c1b3bba0ee59669474f976afb862ccee0026e
+F src/alter.c 87c9b91d15826cbb2d289f4cff3bc5671935ec3b238e307407087e615220788a
 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
 F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929
 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
@@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4
 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
-F src/build.c e9ff9104d6d64dd2a000ca9cc7d25c80a5b1a3fd2422b4e0d84afee8c8bef78b
+F src/build.c 19d9283feae27045cfd5712ae4cabcac91a9b7bf619e651f1571e9637bd7f65d
 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1
@@ -496,16 +496,16 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
 F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
 F src/delete.c 62451bba9fe641159e9c0b7d9d2bab1c48d0cff11e16de2d14000603d2af1fcf
-F src/expr.c b1bcf90afb7dcc0fae4d81116177e3d02e0803f81fd543c10fcd0691390b6adf
+F src/expr.c 84691a9d63baddcc6c735080a9b347e7f6feedb04c293730284999c92af95371
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
-F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4
+F src/fkey.c 1df6ad21908d84adb6d1297d7657ccd239c8ef0836e3a457d1fe15318393933b
 F src/func.c c224240cbc97fa5e9c4fe9acb128716cb835ca045532bca6951b7c45b020c56c
 F src/global.c 5eba017ebbd887e2365e6e6e815e1619e41406b8946d17594e94116174787df5
 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c d560dc585c50e01b015cbf924c173de88f61c8c85b3d1adb9d4865b92fff2d72
+F src/insert.c 6f10127cc5c8bb3631f25bad89f6d2f9c53606df789449f6af7b8647d8f97b4f
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 0aa9e7f08e168e3874cb54984408e3976dafdf5616d511952c425b5ac088ea3e
 F src/main.c 5d024b9b96d9c6809e66b7f4864c3745bc8caf2a6af3b27dc0f05328f4439dfd
@@ -537,7 +537,7 @@ F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb
 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
-F src/pragma.c 9fe75aa29e8706a2cf6b9c1600ac05a2efc55c44ce719b65aa45d10ff58acc9d
+F src/pragma.c e8efa185aaaa4c4036fc40572b74ff9bb5317520c3a1886567093b5ac8b15381
 F src/pragma.h a11b4798f9c49f156f130e1f7041a9fcc9d316a64f3501b6013acdd2e4c6f549
 F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67
 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
@@ -549,7 +549,7 @@ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e
 F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
-F src/sqliteInt.h e2fbf849a7e0ee1842a4775952a61c966f9eb25075297dd2f3aff5b5e4418415
+F src/sqliteInt.h ea94bc5f087522abe62550bb73ef1d7f78d28337fc3834cd676ef39d143ef2c2
 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -611,7 +611,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
 F src/treeview.c 43f88d0fd19976a60aee6867959213b438593276f1e8179048df85f416a1ab19
 F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222
-F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d
+F src/update.c d2648c47202cf54104c94b427209be0350e667fbf4b825a61cae54ef86aaf1d9
 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
 F src/util.c 6ca9cf268dfaf2393866990788c0797240e20e7ba7e3a22cd076e6a3c7b1a132
@@ -626,7 +626,7 @@ F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64
 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2
 F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724
 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
-F src/vtab.c 3a9a6ae1fd14f7c00af184233cb9f3bced89ae277a75a312f85fb77297a3cdfa
+F src/vtab.c 516cb50e2a57359155db7f71d98f1690dc9cae84d359a1c6801b2615dc3cf362
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c
 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
@@ -1920,7 +1920,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 3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902
-R 6b5f2c664834813a7df89f39b77ebda9
+P d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f
+R 2bd36d7d73ef054d58c2b5fa1473f7b9
 U drh
-Z 12d963d3ccf8007e48d95666e4982a9e
+Z d1f622cc8631b67a8482f1c93905c30a
index 639f1a3b267c2d52c89c4dfa1f15a357010f7518..c4363aa39ebc5b981f899d33261dcced718af990 100644 (file)
@@ -1 +1 @@
-d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f
\ No newline at end of file
+8646547e54211d44c415663c33775c4268550f8332949c4731a4bb6ec9cc663a
\ No newline at end of file
index c29be3f6e00d4154edd44ba896890c280d03f019..1d1e2d811bb440d7a2953e22787d365c74c94584 100644 (file)
@@ -337,7 +337,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
   zDb = db->aDb[iDb].zDbSName;
   zTab = &pNew->zName[16];  /* Skip the "sqlite_altertab_" prefix on the name */
   pCol = &pNew->aCol[pNew->nCol-1];
-  pDflt = pCol->pDflt;
+  pDflt = sqlite3ColumnExpr(pNew, pCol);
   pTab = sqlite3FindTable(db, zTab, zDb);
   assert( pTab );
 
@@ -539,8 +539,8 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
     pCol->zName = sqlite3DbStrDup(db, pCol->zName);
     pCol->hName = sqlite3StrIHash(pCol->zName);
     pCol->zColl = 0;
-    pCol->pDflt = 0;
   }
+  pNew->pDfltList = sqlite3ExprListDup(db, pTab->pDfltList, 0);
   pNew->pSchema = db->aDb[iDb].pSchema;
   pNew->addColOffset = pTab->addColOffset;
   pNew->nTabRef = 1;
@@ -1528,7 +1528,9 @@ static void renameColumnFunc(
         }
 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
         for(i=0; i<sParse.pNewTable->nCol; i++){
-          sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt);
+          Expr *pExpr = sqlite3ColumnExpr(sParse.pNewTable,
+                                                  &sParse.pNewTable->aCol[i]);
+          sqlite3WalkExpr(&sWalker, pExpr);
         }
 #endif
       }
@@ -1874,7 +1876,9 @@ static void renameQuotefixFunc(
           sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck);
 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
           for(i=0; i<sParse.pNewTable->nCol; i++){
-            sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt);
+            sqlite3WalkExpr(&sWalker, 
+               sqlite3ColumnExpr(sParse.pNewTable, 
+                                         &sParse.pNewTable->aCol[i]));
           }
 #endif /* SQLITE_OMIT_GENERATED_COLUMNS */
         }
index 8b45df3cad07f849f556d7a7b545b3b0233a562f..33f0015fd7f0bec29b7e1c51367cf1ca78929ce3 100644 (file)
@@ -667,6 +667,42 @@ void sqlite3CommitInternalChanges(sqlite3 *db){
   db->mDbFlags &= ~DBFLAG_SchemaChange;
 }
 
+/*
+** Set the expression associated with a column.  This is usually
+** the DEFAULT value, but might also be the expression that computes
+** the value for a generated column.
+*/
+void sqlite3ColumnSetExpr(
+  Parse *pParse,    /* Parsing context */
+  Table *pTab,      /* The table containing the column */
+  Column *pCol,     /* The column to receive the new DEFAULT expression */
+  Expr *pExpr       /* The new default expression */
+){
+  ExprList *pList = pTab->pDfltList;
+  if( pCol->iDflt==0
+   || pList==0
+   || pList->nExpr<pCol->iDflt
+  ){
+    pCol->iDflt = pList==0 ? 1 : pList->nExpr+1;
+    pTab->pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr);
+  }else{
+    sqlite3ExprDelete(pParse->db, pList->a[pCol->iDflt-1].pExpr);
+    pList->a[pCol->iDflt-1].pExpr = pExpr;
+  }
+}
+
+/*
+** Return the expression associated with a column.  The expression might be
+** the DEFAULT clause or the AS clause of a generated column.
+** Return NULL if the column has no associated expression.
+*/
+Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
+  if( pCol->iDflt==0 ) return 0;
+  if( pTab->pDfltList==0 ) return 0;
+  if( pTab->pDfltList->nExpr<pCol->iDflt ) return 0;
+  return pTab->pDfltList->a[pCol->iDflt-1].pExpr;
+}
+
 /*
 ** Delete memory allocated for the column names of a table or view (the
 ** Table.aCol[] array).
@@ -679,10 +715,15 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
     for(i=0; i<pTable->nCol; i++, pCol++){
       assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) );
       sqlite3DbFree(db, pCol->zName);
-      sqlite3ExprDelete(db, pCol->pDflt);
       sqlite3DbFree(db, pCol->zColl);
     }
     sqlite3DbFree(db, pTable->aCol);
+    sqlite3ExprListDelete(db, pTable->pDfltList);
+    if( db==0 || db->pnBytesFreed==0 ){
+      pTable->aCol = 0;
+      pTable->nCol = 0;
+      pTable->pDfltList = 0;
+    }
   }
 }
 
@@ -1636,15 +1677,15 @@ void sqlite3AddDefaultValue(
       /* A copy of pExpr is used instead of the original, as pExpr contains
       ** tokens that point to volatile memory.
       */
-      Expr x;
-      sqlite3ExprDelete(db, pCol->pDflt);
+      Expr x, *pDfltExpr;
       memset(&x, 0, sizeof(x));
       x.op = TK_SPAN;
       x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
       x.pLeft = pExpr;
       x.flags = EP_Skip;
-      pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
+      pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
       sqlite3DbFree(db, x.u.zToken);
+      sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr);
     }
   }
   if( IN_RENAME_OBJECT ){
@@ -1868,7 +1909,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
     sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns");
     goto generated_done;
   }
-  if( pCol->pDflt ) goto generated_error;
+  if( pCol->iDflt>0 ) goto generated_error;
   if( pType ){
     if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
       /* no-op */
@@ -1886,7 +1927,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
   if( pCol->colFlags & COLFLAG_PRIMKEY ){
     makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */
   }
-  pCol->pDflt = pExpr;
+  sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr);
   pExpr = 0;
   goto generated_done;
 
@@ -2540,7 +2581,7 @@ void sqlite3EndTable(
     for(ii=0; ii<p->nCol; ii++){
       u32 colFlags = p->aCol[ii].colFlags;
       if( (colFlags & COLFLAG_GENERATED)!=0 ){
-        Expr *pX = p->aCol[ii].pDflt;
+        Expr *pX = sqlite3ColumnExpr(p, &p->aCol[ii]);
         testcase( colFlags & COLFLAG_VIRTUAL );
         testcase( colFlags & COLFLAG_STORED );
         if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){
@@ -2550,8 +2591,8 @@ void sqlite3EndTable(
           ** tree that have been allocated from lookaside memory, which is
           ** illegal in a schema and will lead to errors or heap corruption
           ** when the database connection closes. */
-          sqlite3ExprDelete(db, pX);
-          p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+          sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], 
+               sqlite3ExprAlloc(db, TK_NULL, 0, 0));
         }
       }else{
         nNG++;
@@ -2965,8 +3006,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
   pTable->pSchema->schemaFlags |= DB_UnresetViews;
   if( db->mallocFailed ){
     sqlite3DeleteColumnNames(db, pTable);
-    pTable->aCol = 0;
-    pTable->nCol = 0;
   }
 #endif /* SQLITE_OMIT_VIEW */
   return nErr;  
@@ -2985,8 +3024,6 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){
     Table *pTab = sqliteHashData(i);
     if( pTab->pSelect ){
       sqlite3DeleteColumnNames(db, pTab);
-      pTab->aCol = 0;
-      pTab->nCol = 0;
     }
   }
   DbClearProperty(db, idx, DB_UnresetViews);
index dea26954617d503befe04e47cae4d1714ef1a919..04881be8cace5d23a63793d57a96a9f8e08eac77 100644 (file)
@@ -3643,9 +3643,10 @@ void sqlite3ExprCodeLoadIndexColumn(
 ** and store the result in register regOut
 */
 void sqlite3ExprCodeGeneratedColumn(
-  Parse *pParse,
-  Column *pCol,
-  int regOut
+  Parse *pParse,     /* Parsing context */
+  Table *pTab,       /* Table containing the generated column */
+  Column *pCol,      /* The generated column */
+  int regOut         /* Put the result in this register */
 ){
   int iAddr;
   Vdbe *v = pParse->pVdbe;
@@ -3656,7 +3657,7 @@ void sqlite3ExprCodeGeneratedColumn(
   }else{
     iAddr = 0;
   }
-  sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut);
+  sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut);
   if( pCol->affinity>=SQLITE_AFF_TEXT ){
     sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
   }
@@ -3697,7 +3698,7 @@ void sqlite3ExprCodeGetColumnOfTable(
         int savedSelfTab = pParse->iSelfTab;
         pCol->colFlags |= COLFLAG_BUSY;
         pParse->iSelfTab = iTabCur+1;
-        sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut);
+        sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, regOut);
         pParse->iSelfTab = savedSelfTab;
         pCol->colFlags &= ~COLFLAG_BUSY;
       }
@@ -4031,7 +4032,7 @@ expr_code_doover:
             }
             pCol->colFlags |= COLFLAG_BUSY;
             if( pCol->colFlags & COLFLAG_NOTAVAIL ){
-              sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc);
+              sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, iSrc);
             }
             pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL);
             return iSrc;
index 9f622f40c6ba45d3fea7ba2438937cc6838f66f5..2e743c702225a717ad102c098c8bb2e0496b8d41 100644 (file)
@@ -1279,7 +1279,7 @@ static Trigger *fkActionTrigger(
             testcase( pCol->colFlags & COLFLAG_STORED );
             pDflt = 0;
           }else{
-            pDflt = pCol->pDflt;
+            pDflt = sqlite3ColumnExpr(pFKey->pFrom, pCol);
           }
           if( pDflt ){
             pNew = sqlite3ExprDup(db, pDflt, 0);
index 63ffa5edd0dac8e2211de5c0b61956d946bb8d92..867ab76fd14505cd4f920505c16d41adc0d84758 100644 (file)
@@ -293,7 +293,7 @@ void sqlite3ComputeGeneratedColumns(
         int x;
         pCol->colFlags |= COLFLAG_BUSY;
         w.eCode = 0;
-        sqlite3WalkExpr(&w, pCol->pDflt);
+        sqlite3WalkExpr(&w, sqlite3ColumnExpr(pTab, pCol));
         pCol->colFlags &= ~COLFLAG_BUSY;
         if( w.eCode & COLFLAG_NOTAVAIL ){
           pRedo = pCol;
@@ -302,7 +302,7 @@ void sqlite3ComputeGeneratedColumns(
         eProgress = 1;
         assert( pCol->colFlags & COLFLAG_GENERATED );
         x = sqlite3TableColumnToStorage(pTab, i) + iRegStore;
-        sqlite3ExprCodeGeneratedColumn(pParse, pCol, x);
+        sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, x);
         pCol->colFlags &= ~COLFLAG_NOTAVAIL;
       }
     }
@@ -1088,7 +1088,9 @@ void sqlite3Insert(
       }else if( pColumn==0 ){
         /* Hidden columns that are not explicitly named in the INSERT
         ** get there default value */
-        sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
+        sqlite3ExprCodeFactorable(pParse, 
+            sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
+            iRegStore);
         continue;
       }
     }
@@ -1097,13 +1099,17 @@ void sqlite3Insert(
       if( j>=pColumn->nId ){
         /* A column not named in the insert column list gets its
         ** default value */
-        sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
+        sqlite3ExprCodeFactorable(pParse, 
+            sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
+            iRegStore);
         continue;
       }
       k = j;
     }else if( nColumn==0 ){
       /* This is INSERT INTO ... DEFAULT VALUES.  Load the default value. */
-      sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
+      sqlite3ExprCodeFactorable(pParse, 
+          sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
+          iRegStore);
       continue;
     }else{
       k = i - nHidden;
@@ -1669,7 +1675,7 @@ void sqlite3GenerateConstraintChecks(
         }
         if( onError==OE_Replace ){
           if( b2ndPass        /* REPLACE becomes ABORT on the 2nd pass */
-           || pCol->pDflt==0  /* REPLACE is ABORT if no DEFAULT value */
+           || pCol->iDflt==0  /* REPLACE is ABORT if no DEFAULT value */
           ){
             testcase( pCol->colFlags & COLFLAG_VIRTUAL );
             testcase( pCol->colFlags & COLFLAG_STORED );
@@ -1691,7 +1697,8 @@ void sqlite3GenerateConstraintChecks(
             VdbeCoverage(v);
             assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
             nSeenReplace++;
-            sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg);
+            sqlite3ExprCodeCopy(pParse,
+               sqlite3ColumnExpr(pTab, pCol), iReg);
             sqlite3VdbeJumpHere(v, addr1);
             break;
           }
@@ -2412,7 +2419,7 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
   if( pTab->pSchema->file_format<2 ) return;
 
   for(i=pTab->nCol-1; i>0; i--){
-    if( pTab->aCol[i].pDflt!=0 ) break;
+    if( pTab->aCol[i].iDflt!=0 ) break;
     if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
   }
   sqlite3VdbeChangeP5(v, i+1);
@@ -2829,7 +2836,9 @@ static int xferOptimization(
     ** This requirement could be relaxed for VIRTUAL columns, I suppose.
     */
     if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){
-      if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){
+      if( sqlite3ExprCompare(0,
+             sqlite3ColumnExpr(pSrc, pSrcCol),
+             sqlite3ColumnExpr(pDest, pDestCol), -1)!=0 ){
         testcase( pDestCol->colFlags & COLFLAG_VIRTUAL );
         testcase( pDestCol->colFlags & COLFLAG_STORED );
         return 0;  /* Different generator expressions */
@@ -2847,11 +2856,13 @@ static int xferOptimization(
     }
     /* Default values for second and subsequent columns need to match. */
     if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){
-      assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
-      assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
-      if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) 
-       || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
-                                       pSrcCol->pDflt->u.zToken)!=0)
+      Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol);
+      Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol);
+      assert( pDestExpr==0 || pDestExpr->op==TK_SPAN );
+      assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN );
+      if( (pDestExpr==0)!=(pSrcExpr==0) 
+       || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken,
+                                       pSrcExpr->u.zToken)!=0)
       ){
         return 0;    /* Default values must be the same for all columns */
       }
index e0cf5ced50b7bce2d934bd5cd5265cc9fd47bf98..0427bb972fb7e29f789f820a7e76a75bfdea2eb0 100644 (file)
@@ -1177,13 +1177,16 @@ void sqlite3Pragma(
         }else{
           for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
         }
-        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 );
+        assert( sqlite3ColumnExpr(pTab,pCol)==0
+             || sqlite3ColumnExpr(pTab,pCol)->op==TK_SPAN
+             || isHidden>=2 );
         sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
                i-nHidden,
                pCol->zName,
                sqlite3ColumnType(pCol,""),
                pCol->notNull ? 1 : 0,
-               pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0,
+               isHidden>=2 || sqlite3ColumnExpr(pTab,pCol)==0 ? 0 :
+                          sqlite3ColumnExpr(pTab,pCol)->u.zToken,
                k,
                isHidden);
       }
index 8f63d777ab83bd48735bc0c6868f029e802e5ace..3fbb148d40425a3223cd24dcfcbb7938e4bb6334 100644 (file)
@@ -2031,13 +2031,13 @@ struct Module {
 */
 struct Column {
   char *zName;     /* Name of this column, \000, then the type */
-  Expr *pDflt;     /* Default value or GENERATED ALWAYS AS value */
   char *zColl;     /* Collating sequence.  If NULL, use the default */
-  u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
+  u8 notNull : 4;  /* An OE_ code for handling a NOT NULL constraint */
+  u8 eType : 4;    /* One of the standard types */
   char affinity;   /* One of the SQLITE_AFF_... values */
   u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
   u8 hName;        /* Column name hash for faster lookup */
-  u8 eType;        /* One of the standard types */
+  u16 iDflt;       /* 1-based index of DEFAULT.  0 means "none" */
   u16 colFlags;    /* Boolean properties.  See COLFLAG_ defines below */
 };
 
@@ -2213,6 +2213,7 @@ struct Table {
   char *zColAff;       /* String defining the affinity of each column */
   ExprList *pCheck;    /* All CHECK constraints */
                        /*   ... also used as column name list in a VIEW */
+  ExprList *pDfltList; /* DEFAULT clauses on various columns */
   Pgno tnum;           /* Root BTree page for this table */
   u32 nTabRef;         /* Number of pointers to this Table */
   u32 tabFlags;        /* Mask of TF_* values */
@@ -4379,6 +4380,8 @@ void sqlite3ResetAllSchemasOfConnection(sqlite3*);
 void sqlite3ResetOneSchema(sqlite3*,int);
 void sqlite3CollapseDatabaseArray(sqlite3*);
 void sqlite3CommitInternalChanges(sqlite3*);
+void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*);
+Expr *sqlite3ColumnExpr(Table*,Column*);
 void sqlite3DeleteColumnNames(sqlite3*,Table*);
 void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect);
 int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
@@ -4517,7 +4520,7 @@ void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
 void sqlite3ExprCodeMove(Parse*, int, int, int);
 void sqlite3ExprCode(Parse*, Expr*, int);
 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
-void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int);
+void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);
 #endif
 void sqlite3ExprCodeCopy(Parse*, Expr*, int);
 void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
index c5a01f89693a4b1541259254bba90f1438d8cd98..f93d85bd5eb09955f878659d5acc3d35159d6e80 100644 (file)
@@ -66,7 +66,8 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
     Column *pCol = &pTab->aCol[i];
     VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
     assert( i<pTab->nCol );
-    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
+    sqlite3ValueFromExpr(sqlite3VdbeDb(v), 
+                         sqlite3ColumnExpr(pTab,pCol), enc, 
                          pCol->affinity, &pValue);
     if( pValue ){
       sqlite3VdbeAppendP4(v, pValue, P4_MEM);
@@ -526,8 +527,10 @@ void sqlite3Update(
       for(i=0; i<pTab->nCol; i++){
         if( aXRef[i]>=0 ) continue;
         if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue;
-        if( sqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt,
-                                               aXRef, chngRowid) ){
+        if( sqlite3ExprReferencesUpdatedColumn(
+                sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
+                 aXRef, chngRowid)
+        ){
           aXRef[i] = 99999;
           bProgress = 1;
         }
index 1a9457c24d2e6f18d248877572214fbed8abfbdc..25672bcce095cc1903bc542a239fbfec3a33cd9d 100644 (file)
@@ -829,10 +829,12 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
       Table *pNew = sParse.pNewTable;
       Index *pIdx;
       pTab->aCol = pNew->aCol;
+      pTab->pDfltList = pNew->pDfltList;
       pTab->nNVCol = pTab->nCol = pNew->nCol;
       pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
       pNew->nCol = 0;
       pNew->aCol = 0;
+      pNew->pDfltList = 0;
       assert( pTab->pIndex==0 );
       assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
       if( !HasRowid(pNew)