diff options
author | drh <drh@noemail.net> | 2019-10-18 02:19:18 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-10-18 02:19:18 +0000 |
commit | 9942ef0d95c5a34bec24b669f454fc157bbf8eee (patch) | |
tree | 036d7af16e3d418d65049fd8090a690a5ae039a6 /src/expr.c | |
parent | 0b0b3a95d025430c83563ee390656901734f9988 (diff) | |
download | sqlite-9942ef0d95c5a34bec24b669f454fc157bbf8eee.tar.gz sqlite-9942ef0d95c5a34bec24b669f454fc157bbf8eee.zip |
STORED columns can now reference other STORED columns, in any order, as long
as there are not loops.
FossilOrigin-Name: 0d236698e64b2a4b46f91a25279c406e0bf392fe66116678456f0a034c11d7b4
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/src/expr.c b/src/expr.c index c21006b11..c026c9583 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3577,19 +3577,49 @@ expr_code_doover: } if( iTab<0 ){ if( pParse->iSelfTab<0 ){ - /* Generating CHECK constraints or inserting into partial index */ - assert( pExpr->y.pTab!=0 ); + /* Other columns in the same row for CHECK constraints or + ** generated columns or for inserting into partial index. + ** The row is unpacked into registers beginning at + ** 0-(pParse->iSelfTab). The rowid (if any) is in a register + ** immediately prior to the first column. + */ + Column *pCol; + Table *pTab = pExpr->y.pTab; + int iSrc; + assert( pTab!=0 ); assert( pExpr->iColumn>=XN_ROWID ); assert( pExpr->iColumn<pExpr->y.pTab->nCol ); - if( pExpr->iColumn>=0 - && pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL - ){ - sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab, - target); + if( pExpr->iColumn<0 ){ + return -1-pParse->iSelfTab; + } + pCol = pTab->aCol + pExpr->iColumn; + iSrc = sqlite3ColumnOfTable(pTab, pExpr->iColumn) - pParse->iSelfTab; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zName); + return 0; + } + pCol->colFlags |= COLFLAG_BUSY; + if( pCol->colFlags & COLFLAG_VIRTUAL ){ + target = sqlite3ExprCodeTarget(pParse, pCol->pDflt, target); + }else{ + target = iSrc; + if( pCol->colFlags & COLFLAG_NOTAVAIL ){ + sqlite3ExprCode(pParse, pCol->pDflt, iSrc); + } + } + pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); + return target; + }else +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + if( pCol->affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target); sqlite3VdbeAddOp1(v, OP_RealAffinity, target); return target; }else{ - return pExpr->iColumn - pParse->iSelfTab; + return iSrc; } }else{ /* Coding an expression that is part of an index where column names |