diff options
author | drh <drh@noemail.net> | 2019-10-22 13:01:24 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-10-22 13:01:24 +0000 |
commit | 427b96aedf422b1a8e906e47e8852033c70939c4 (patch) | |
tree | bafbbb3a6d6bc0146d7d7829ec22d9c7eecfb9bf /src | |
parent | 6b910364bbf531670aa0c02ad004bcdf2f5b66ad (diff) | |
download | sqlite-427b96aedf422b1a8e906e47e8852033c70939c4.tar.gz sqlite-427b96aedf422b1a8e906e47e8852033c70939c4.zip |
New testcase() macros. Fix a problem with INSERT when the IPK is to the
right of generated columns.
FossilOrigin-Name: 412799fc5527aaca987e4e04b8a4f774dcdb70fb80e3a126dc3a26d48a66935c
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 8 | ||||
-rw-r--r-- | src/insert.c | 28 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/update.c | 12 |
4 files changed, 40 insertions, 9 deletions
diff --git a/src/build.c b/src/build.c index ad65c25ef..2ba939822 100644 --- a/src/build.c +++ b/src/build.c @@ -2207,11 +2207,15 @@ void sqlite3EndTable( } #endif /* !defined(SQLITE_OMIT_CHECK) */ #ifndef SQLITE_OMIT_GENERATED_COLUMNS - if( p->tabFlags & (TF_HasVirtual|TF_HasStored) ){ + if( p->tabFlags & TF_HasGenerated ){ int ii; + testcase( p->tabFlags & TF_HasVirtual ); + testcase( p->tabFlags & TF_HasStored ); for(ii=0; ii<p->nCol; ii++){ u32 colFlags = p->aCol[ii].colFlags; - if( (colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL))!=0 ){ + if( (colFlags & COLFLAG_GENERATED)!=0 ){ + testcase( colFlags & COLFLAG_VIRTUAL ); + testcase( colFlags & COLFLAG_STORED ); sqlite3ResolveSelfReference(pParse, p, NC_GenCol, p->aCol[ii].pDflt, 0); } diff --git a/src/insert.c b/src/insert.c index c90f9d272..1995f9634 100644 --- a/src/insert.c +++ b/src/insert.c @@ -222,6 +222,8 @@ void sqlite3ComputeGeneratedColumns( */ for(i=0; i<pTab->nCol; i++){ if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colflags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colflags & COLFLAG_STORED ); pTab->aCol[i].colFlags |= COLFLAG_NOTAVAIL; } } @@ -854,6 +856,19 @@ void sqlite3Insert( */ if( pColumn==0 && nColumn>0 ){ ipkColumn = pTab->iPKey; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasGenerated ); + for(i=ipkColumn-1; i>=0; i--){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_GENERATED ); + ipkColumn--; + } + } + } +#endif } /* Make sure the number of columns in the source data matches the number @@ -1070,7 +1085,9 @@ void sqlite3Insert( ** columns have already been computed. This must be done after ** computing the ROWID in case one of the generated columns ** refers to the ROWID. */ - if( pTab->tabFlags & (TF_HasStored|TF_HasVirtual) ){ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab); } #endif @@ -1139,7 +1156,9 @@ void sqlite3Insert( ** columns have already been computed. This must be done after ** computing the ROWID in case one of the generated columns ** refers to the ROWID. */ - if( pTab->tabFlags & (TF_HasStored|TF_HasVirtual) ){ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab); } #endif @@ -1486,7 +1505,6 @@ void sqlite3GenerateConstraintChecks( testcase( i!=sqlite3TableColumnToStorage(pTab, i) ); testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); - testcase( pTab->aCol[i].colFlags & COLFLAG_GENERATED ); iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1; switch( onError ){ case OE_Replace: { @@ -2422,7 +2440,9 @@ static int xferOptimization( /* Generator expressions for generated columns must match */ if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){ - return 0; /* Different generator expressions */ + testcase( pDestCol->colflags & COLFLAG_VIRTUAL ); + testcase( pDestCol->colflags & COLFLAG_STORED ); + return 0; /* Different generator expressions */ } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c9dee9e23..06464acb5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2037,6 +2037,7 @@ struct Table { #define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ #define TF_HasVirtual 0x0020 /* Has one or more VIRTUAL columns */ #define TF_HasStored 0x0040 /* Has one or more STORED columns */ +#define TF_HasGenerated 0x0060 /* Combo: HasVirtual + HasStored */ #define TF_WithoutRowid 0x0080 /* No rowid. PRIMARY KEY is the key */ #define TF_StatsUsed 0x0100 /* Query planner decisions affected by ** Index.aiRowLogEst[] values */ diff --git a/src/update.c b/src/update.c index 79b6fbd2a..48413a0df 100644 --- a/src/update.c +++ b/src/update.c @@ -313,7 +313,9 @@ void sqlite3Update( chngPk = 1; } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - else if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ + else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); sqlite3ErrorMsg(pParse, "cannot UPDATE generated column \"%s\"", pTab->aCol[j].zName); @@ -693,7 +695,9 @@ void sqlite3Update( } } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - if( pTab->tabFlags & (TF_HasStored|TF_HasVirtual) ){ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); } #endif @@ -737,7 +741,9 @@ void sqlite3Update( } } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - if( pTab->tabFlags & (TF_HasStored|TF_HasVirtual) ){ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); } #endif |