Initial experimental code for generated column support. Non-functional.
FossilOrigin-Name: 11d472c1df707b8d03ec57d8fc582a34f5eb89a9d02a154a9871650c65065b45
diff --git a/src/resolve.c b/src/resolve.c
index e66dc18..6577468 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -414,7 +414,7 @@
if( cnt==0
&& cntTab==1
&& pMatch
- && (pNC->ncFlags & NC_IdxExpr)==0
+ && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
&& sqlite3IsRowid(zCol)
&& VisibleRowid(pMatch->pTab)
){
@@ -625,13 +625,16 @@
const char *zMsg, /* Type of error */
int validMask /* Set of contexts for which prohibited */
){
- assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
+ assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 );
if( (pNC->ncFlags & validMask)!=0 ){
const char *zIn = "partial index WHERE clauses";
if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
#ifndef SQLITE_OMIT_CHECK
else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
#endif
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ else if( pNC->ncFlags & NC_GenCol ) zIn = "GENERATED ALWAYS AS columns";
+#endif
sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
}
}
@@ -723,7 +726,7 @@
zColumn = pExpr->u.zToken;
}else{
Expr *pLeft = pExpr->pLeft;
- notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
+ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr|NC_GenCol);
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
@@ -820,7 +823,7 @@
** sqlite_version() that might change over time cannot be used
** in an index. */
notValid(pParse, pNC, "non-deterministic functions",
- NC_IdxExpr|NC_PartIdx);
+ NC_IdxExpr|NC_PartIdx|NC_GenCol);
}
if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0
@@ -964,7 +967,8 @@
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
- notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+ notValid(pParse, pNC, "subqueries",
+ NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol);
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
@@ -975,7 +979,8 @@
break;
}
case TK_VARIABLE: {
- notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+ notValid(pParse, pNC, "parameters",
+ NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol);
break;
}
case TK_IS:
@@ -1788,6 +1793,7 @@
** (2) WHERE clauses on partial indices
** (3) Expressions in indexes on expressions
** (4) Expression arguments to VACUUM INTO.
+** (5) GENERATED ALWAYS as expressions
**
** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
** nodes of the expression is set to -1 and the Expr.iColumn value is
@@ -1796,18 +1802,19 @@
** Any errors cause an error message to be set in pParse.
*/
int sqlite3ResolveSelfReference(
- Parse *pParse, /* Parsing context */
- Table *pTab, /* The table being referenced, or NULL */
- int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
- Expr *pExpr, /* Expression to resolve. May be NULL. */
- ExprList *pList /* Expression list to resolve. May be NULL. */
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* The table being referenced, or NULL */
+ int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */
+ Expr *pExpr, /* Expression to resolve. May be NULL. */
+ ExprList *pList /* Expression list to resolve. May be NULL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
int rc;
assert( type==0 || pTab!=0 );
- assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
+ || type==NC_GenCol || pTab==0 );
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
if( pTab ){