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: |
4ad66af04a654d92711d2d056ce8f35c |
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
Changes to src/build.c.
︙ | ︙ | |||
897 898 899 900 901 902 903 | ** ** 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 ); | | | 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->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 | /* no-op */ }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){ eType = COLFLAG_STORED; }else{ goto generated_error; } } | < | 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; } } 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 | if( pEnd==0 && pSelect==0 ){ return; } assert( !db->mallocFailed ); p = pParse->pNewTable; if( p==0 ) return; 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. | > | 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 | 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++){ | > | > > > > | 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( (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 | 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) ){ | | < | 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, pTab->nNVCol); 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 | VdbeComment((v, "Do IPK REPLACE")); sqlite3VdbeJumpHere(v, ipkBottom); } /* Generate the table record */ if( HasRowid(pTab) ){ int regRec = aRegIdx[ix]; | | < | 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, pTab->nNVCol, regRec); sqlite3SetMakeRecordP5(v, pTab); if( !bAffinityDone ){ sqlite3TableAffinity(v, pTab, 0); } } *pbMayReplace = seenReplace; |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
1582 1583 1584 1585 1586 1587 1588 | } 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 */ | | | 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->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 | 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 */ | | | 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 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 |
︙ | ︙ |