/ Check-in [4ad66af0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In the Table object, change the nVCol field to nNVCol - the number of non-virtual columns, as that is the quantity that we need most.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | generated-columns
Files: files | file ages | folders
SHA3-256: 4ad66af04a654d92711d2d056ce8f35cd21eac4b99fb8d78be1a314620b6d29e
User & Date: drh 2019-10-17 18:35:57
Context
2019-10-18
02:19
STORED columns can now reference other STORED columns, in any order, as long as there are not loops. check-in: 0d236698 user: drh tags: generated-columns
2019-10-17
18:35
In the Table object, change the nVCol field to nNVCol - the number of non-virtual columns, as that is the quantity that we need most. check-in: 4ad66af0 user: drh tags: generated-columns
18:07
Bug fix with INSERT using an explicit column list on a table with a non-final STORED column. check-in: 61b4459a user: drh tags: generated-columns
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

   897    897   **
   898    898   ** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro
   899    899   */
   900    900   i16 sqlite3ColumnOfTable(Table *pTab, i16 iCol){
   901    901     int i;
   902    902     i16 n;
   903    903     assert( iCol<pTab->nCol );
   904         -  if( pTab->nVCol==0 ) return iCol;
          904  +  if( (pTab->tabFlags & TF_HasVirtual)==0 ) return iCol;
   905    905     for(i=0, n=0; i<iCol; i++){
   906    906       if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
   907    907     }
   908    908     return n;    
   909    909   }
   910    910   #endif
   911    911   
................................................................................
  1560   1560         /* no-op */
  1561   1561       }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
  1562   1562         eType = COLFLAG_STORED;
  1563   1563       }else{
  1564   1564         goto generated_error;
  1565   1565       }
  1566   1566     }
  1567         -  if( eType==COLFLAG_VIRTUAL ) pTab->nVCol++;
  1568   1567     pCol->colFlags |= eType;
  1569   1568     assert( TF_HasVirtual==COLFLAG_VIRTUAL );
  1570   1569     assert( TF_HasStored==COLFLAG_STORED );
  1571   1570     pTab->tabFlags |= eType;
  1572   1571     pCol->pDflt = sqlite3ExprDup(pParse->db, pExpr, 0);
  1573   1572     goto generated_done;
  1574   1573   
................................................................................
  2123   2122   
  2124   2123     if( pEnd==0 && pSelect==0 ){
  2125   2124       return;
  2126   2125     }
  2127   2126     assert( !db->mallocFailed );
  2128   2127     p = pParse->pNewTable;
  2129   2128     if( p==0 ) return;
         2129  +  p->nNVCol = p->nCol;
  2130   2130   
  2131   2131     if( pSelect==0 && isShadowTableName(db, p->zName) ){
  2132   2132       p->tabFlags |= TF_Shadow;
  2133   2133     }
  2134   2134   
  2135   2135     /* If the db->init.busy is 1 it means we are reading the SQL off the
  2136   2136     ** "sqlite_master" or "sqlite_temp_master" table on the disk.
................................................................................
  2179   2179       sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
  2180   2180     }
  2181   2181   #endif /* !defined(SQLITE_OMIT_CHECK) */
  2182   2182   #ifndef SQLITE_OMIT_GENERATED_COLUMNS
  2183   2183     if( p->tabFlags & (TF_HasVirtual|TF_HasStored) ){
  2184   2184       int ii;
  2185   2185       for(ii=0; ii<p->nCol; ii++){
  2186         -      if( (p->aCol[ii].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL))!=0 ){
         2186  +      u32 colFlags = p->aCol[ii].colFlags;
         2187  +      if( (colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL))!=0 ){
         2188  +        if( colFlags & COLFLAG_VIRTUAL ){
         2189  +          p->nNVCol--;
         2190  +          assert( p->nNVCol>=0 );
         2191  +        }
  2187   2192           sqlite3ResolveSelfReference(pParse, p, NC_GenCol, 
  2188   2193                                       p->aCol[ii].pDflt, 0);
  2189   2194         }
  2190   2195       }
  2191   2196     }
  2192   2197   #endif
  2193   2198   

Changes to src/insert.c.

    33     33     Vdbe *v;
    34     34     assert( !IsVirtual(pTab) );
    35     35     v = sqlite3GetVdbe(pParse);
    36     36     assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
    37     37     sqlite3TableLock(pParse, iDb, pTab->tnum, 
    38     38                      (opcode==OP_OpenWrite)?1:0, pTab->zName);
    39     39     if( HasRowid(pTab) ){
    40         -    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb,
    41         -                         pTab->nCol - pTab->nVCol);
           40  +    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol);
    42     41       VdbeComment((v, "%s", pTab->zName));
    43     42     }else{
    44     43       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
    45     44       assert( pPk!=0 );
    46     45       assert( pPk->tnum==pTab->tnum );
    47     46       sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
    48     47       sqlite3VdbeSetP4KeyInfo(pParse, pPk);
................................................................................
  1929   1928       VdbeComment((v, "Do IPK REPLACE"));
  1930   1929       sqlite3VdbeJumpHere(v, ipkBottom);
  1931   1930     }
  1932   1931   
  1933   1932     /* Generate the table record */
  1934   1933     if( HasRowid(pTab) ){
  1935   1934       int regRec = aRegIdx[ix];
  1936         -    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1,
  1937         -                      pTab->nCol-pTab->nVCol, regRec);
         1935  +    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec);
  1938   1936       sqlite3SetMakeRecordP5(v, pTab);
  1939   1937       if( !bAffinityDone ){
  1940   1938         sqlite3TableAffinity(v, pTab, 0);
  1941   1939       }
  1942   1940     }
  1943   1941   
  1944   1942     *pbMayReplace = seenReplace;

Changes to src/pragma.c.

  1582   1582           }
  1583   1583           assert( pParse->nMem>=8+j );
  1584   1584           assert( sqlite3NoTempsInRange(pParse,1,7+j) );
  1585   1585           sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
  1586   1586           loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
  1587   1587           if( !isQuick ){
  1588   1588             /* Sanity check on record header decoding */
  1589         -          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-pTab->nVCol-1,3);
         1589  +          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3);
  1590   1590             sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
  1591   1591           }
  1592   1592           /* Verify that all NOT NULL columns really are NOT NULL */
  1593   1593           for(j=0; j<pTab->nCol; j++){
  1594   1594             char *zErr;
  1595   1595             int jmp2;
  1596   1596             if( j==pTab->iPKey ) continue;

Changes to src/sqliteInt.h.

  1978   1978     ExprList *pCheck;    /* All CHECK constraints */
  1979   1979                          /*   ... also used as column name list in a VIEW */
  1980   1980     int tnum;            /* Root BTree page for this table */
  1981   1981     u32 nTabRef;         /* Number of pointers to this Table */
  1982   1982     u32 tabFlags;        /* Mask of TF_* values */
  1983   1983     i16 iPKey;           /* If not negative, use aCol[iPKey] as the rowid */
  1984   1984     i16 nCol;            /* Number of columns in this table */
  1985         -  i16 nVCol;           /* Number of virtual columns */
         1985  +  i16 nNVCol;          /* Number of columns that are not VIRTUAL */
  1986   1986     LogEst nRowLogEst;   /* Estimated rows in table - from sqlite_stat1 table */
  1987   1987     LogEst szTabRow;     /* Estimated size of each table row in bytes */
  1988   1988   #ifdef SQLITE_ENABLE_COSTMULT
  1989   1989     LogEst costMult;     /* Cost multiplier for using this table */
  1990   1990   #endif
  1991   1991     u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
  1992   1992   #ifndef SQLITE_OMIT_ALTERTABLE