SQLite

Check-in [4ad66af04a]
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
Timelines: family | ancestors | descendants | both | generated-columns
Files: files | file ages | folders
SHA3-256: 4ad66af04a654d92711d2d056ce8f35cd21eac4b99fb8d78be1a314620b6d29e
User & Date: drh 2019-10-17 18:35:57.978
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: 0d236698e6 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: 4ad66af04a 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: 61b4459ae6 user: drh tags: generated-columns)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/build.c.
897
898
899
900
901
902
903
904

905
906
907
908
909
910
911
897
898
899
900
901
902
903

904
905
906
907
908
909
910
911







-
+







**
** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro
*/
i16 sqlite3ColumnOfTable(Table *pTab, i16 iCol){
  int i;
  i16 n;
  assert( iCol<pTab->nCol );
  if( pTab->nVCol==0 ) return iCol;
  if( (pTab->tabFlags & TF_HasVirtual)==0 ) return iCol;
  for(i=0, n=0; i<iCol; i++){
    if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
  }
  return n;    
}
#endif

1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573







-







      /* no-op */
    }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
      eType = COLFLAG_STORED;
    }else{
      goto generated_error;
    }
  }
  if( eType==COLFLAG_VIRTUAL ) pTab->nVCol++;
  pCol->colFlags |= eType;
  assert( TF_HasVirtual==COLFLAG_VIRTUAL );
  assert( TF_HasStored==COLFLAG_STORED );
  pTab->tabFlags |= eType;
  pCol->pDflt = sqlite3ExprDup(pParse->db, pExpr, 0);
  goto generated_done;

2123
2124
2125
2126
2127
2128
2129

2130
2131
2132
2133
2134
2135
2136
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136







+








  if( pEnd==0 && pSelect==0 ){
    return;
  }
  assert( !db->mallocFailed );
  p = pParse->pNewTable;
  if( p==0 ) return;
  p->nNVCol = p->nCol;

  if( pSelect==0 && isShadowTableName(db, p->zName) ){
    p->tabFlags |= TF_Shadow;
  }

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
2179
2180
2181
2182
2183
2184
2185

2186





2187
2188
2189
2190
2191
2192
2193
2179
2180
2181
2182
2183
2184
2185
2186

2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198







+
-
+
+
+
+
+







    sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  if( p->tabFlags & (TF_HasVirtual|TF_HasStored) ){
    int ii;
    for(ii=0; ii<p->nCol; ii++){
      u32 colFlags = p->aCol[ii].colFlags;
      if( (p->aCol[ii].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL))!=0 ){
      if( (colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL))!=0 ){
        if( colFlags & COLFLAG_VIRTUAL ){
          p->nNVCol--;
          assert( p->nNVCol>=0 );
        }
        sqlite3ResolveSelfReference(pParse, p, NC_GenCol, 
                                    p->aCol[ii].pDflt, 0);
      }
    }
  }
#endif

Changes to src/insert.c.
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
33
34
35
36
37
38
39

40

41
42
43
44
45
46
47







-
+
-







  Vdbe *v;
  assert( !IsVirtual(pTab) );
  v = sqlite3GetVdbe(pParse);
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite3TableLock(pParse, iDb, pTab->tnum, 
                   (opcode==OP_OpenWrite)?1:0, pTab->zName);
  if( HasRowid(pTab) ){
    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb,
    sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol);
                         pTab->nCol - pTab->nVCol);
    VdbeComment((v, "%s", pTab->zName));
  }else{
    Index *pPk = sqlite3PrimaryKeyIndex(pTab);
    assert( pPk!=0 );
    assert( pPk->tnum==pTab->tnum );
    sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
1929
1930
1931
1932
1933
1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1944
1928
1929
1930
1931
1932
1933
1934

1935

1936
1937
1938
1939
1940
1941
1942







-
+
-







    VdbeComment((v, "Do IPK REPLACE"));
    sqlite3VdbeJumpHere(v, ipkBottom);
  }

  /* Generate the table record */
  if( HasRowid(pTab) ){
    int regRec = aRegIdx[ix];
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1,
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec);
                      pTab->nCol-pTab->nVCol, regRec);
    sqlite3SetMakeRecordP5(v, pTab);
    if( !bAffinityDone ){
      sqlite3TableAffinity(v, pTab, 0);
    }
  }

  *pbMayReplace = seenReplace;
Changes to src/pragma.c.
1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
1592
1593
1594
1595
1596







-
+







        }
        assert( pParse->nMem>=8+j );
        assert( sqlite3NoTempsInRange(pParse,1,7+j) );
        sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
        if( !isQuick ){
          /* Sanity check on record header decoding */
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-pTab->nVCol-1,3);
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3);
          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
        }
        /* Verify that all NOT NULL columns really are NOT NULL */
        for(j=0; j<pTab->nCol; j++){
          char *zErr;
          int jmp2;
          if( j==pTab->iPKey ) continue;
Changes to src/sqliteInt.h.
1978
1979
1980
1981
1982
1983
1984
1985

1986
1987
1988
1989
1990
1991
1992
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992







-
+







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