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 ){