/ Check-in [11d472c1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial experimental code for generated column support. Non-functional.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | generated-columns
Files: files | file ages | folders
SHA3-256: 11d472c1df707b8d03ec57d8fc582a34f5eb89a9d02a154a9871650c65065b45
User & Date: drh 2019-10-16 12:18:59
Context
2019-10-16
19:31
Simple INSERT and SELECT operations working with VIRTUAL columns. check-in: 7f9f90b1 user: drh tags: generated-columns
12:18
Initial experimental code for generated column support. Non-functional. check-in: 11d472c1 user: drh tags: generated-columns
2019-10-15
19:01
Formatting change on a multi-line conditional, for improved clarity. No logic changes. check-in: 7248e347 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

   884    884     int i;
   885    885     for(i=0; i<pIdx->nColumn; i++){
   886    886       if( iCol==pIdx->aiColumn[i] ) return i;
   887    887     }
   888    888     return -1;
   889    889   }
   890    890   
          891  +#ifndef SQLITE_OMIT_GENERATED_COLUMNS
          892  +/*
          893  +** Of the iCol-th column in table pTab, return the index of that column
          894  +** as stored on disk.  Usually the return value is the same as the iCol
          895  +** input, however the return value may be less there are prior VIRTUAL
          896  +** columns.
          897  +**
          898  +** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro
          899  +*/
          900  +i16 sqlite3ColumnOfTable(Table *pTab, i16 iCol){
          901  +  int i;
          902  +  i16 n;
          903  +  assert( iCol<pTab->nCol );
          904  +  if( pTab->nVCol==0 ) return iCol;
          905  +  for(i=0, n=0; i<iCol; i++){
          906  +    if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
          907  +  }
          908  +  return n;    
          909  +}
          910  +#endif
          911  +
   891    912   /*
   892    913   ** Begin constructing a new table representation in memory.  This is
   893    914   ** the first of several action routines that get called in response
   894    915   ** to a CREATE TABLE statement.  In particular, this routine is called
   895    916   ** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
   896    917   ** flag is true if the table should be stored in the auxiliary database
   897    918   ** file instead of in the main database file.  This is normally the case
................................................................................
  1515   1536           pIdx->azColl[0] = p->aCol[i].zColl;
  1516   1537         }
  1517   1538       }
  1518   1539     }else{
  1519   1540       sqlite3DbFree(db, zColl);
  1520   1541     }
  1521   1542   }
         1543  +
         1544  +/* Change the most recently parsed column to be a GENERATED ALWAYS AS
         1545  +** column.
         1546  +*/
         1547  +void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
         1548  +#ifndef SQLITE_OMIT_GENERATED_COLUMNS
         1549  +  u8 eType = COLFLAG_VIRTUAL;
         1550  +  Table *pTab = pParse->pNewTable;
         1551  +  Column *pCol;
         1552  +  if( IN_RENAME_OBJECT ){
         1553  +    sqlite3RenameExprUnmap(pParse, pExpr);
         1554  +  }
         1555  +  if( pTab==0 ) goto generated_done;
         1556  +  pCol = &(pTab->aCol[pTab->nCol-1]);
         1557  +  if( pCol->pDflt ) goto generated_error;
         1558  +  if( pType ){
         1559  +    if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
         1560  +      /* no-op */
         1561  +    }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
         1562  +      eType = COLFLAG_STORED;
         1563  +    }else{
         1564  +      goto generated_error;
         1565  +    }
         1566  +  }
         1567  +  pTab->nVCol++;
         1568  +  pCol->colFlags |= eType;
         1569  +  pCol->pDflt = sqlite3ExprDup(pParse->db, pExpr, 0);
         1570  +  goto generated_done;
         1571  +
         1572  +generated_error:
         1573  +  sqlite3ErrorMsg(pParse, "bad GENERATED ALWAYS AS clause on column \"%s\"",
         1574  +                  pCol->zName);
         1575  +generated_done:
         1576  +  sqlite3ExprDelete(pParse->db, pExpr);
         1577  +#else
         1578  +  /* Throw and error for the GENERATED ALWAYS AS clause if the
         1579  +  ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */
         1580  +  sqlite3ErrorMsg(pParse, "GENERATED ALWAYS AS not supported");
         1581  +  sqlite3ExprDelete(pParse->db, pExpr);
         1582  +#endif
         1583  +}
  1522   1584   
  1523   1585   /*
  1524   1586   ** This function returns the collation sequence for database native text
  1525   1587   ** encoding identified by the string zName, length nName.
  1526   1588   **
  1527   1589   ** If the requested collation sequence is not available, or not available
  1528   1590   ** in the database native encoding, the collation factory is invoked to
................................................................................
  2110   2172   #ifndef SQLITE_OMIT_CHECK
  2111   2173     /* Resolve names in all CHECK constraint expressions.
  2112   2174     */
  2113   2175     if( p->pCheck ){
  2114   2176       sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
  2115   2177     }
  2116   2178   #endif /* !defined(SQLITE_OMIT_CHECK) */
         2179  +#ifndef SQLITE_OMIT_GENERATED_COLUMNS
         2180  +  if( p->nVCol ){
         2181  +    int ii;
         2182  +    for(ii=0; ii<p->nCol; ii++){
         2183  +      if( (p->aCol[ii].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL))!=0 ){
         2184  +        sqlite3ResolveSelfReference(pParse, p, NC_GenCol, 
         2185  +                                    p->aCol[ii].pDflt, 0);
         2186  +      }
         2187  +    }
         2188  +  }
         2189  +#endif
  2117   2190   
  2118   2191     /* Estimate the average row size for the table and for all implied indices */
  2119   2192     estimateTableWidth(p);
  2120   2193     for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
  2121   2194       estimateIndexWidth(pIdx);
  2122   2195     }
  2123   2196   

Changes to src/delete.c.

   471    471         sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
   472    472       }
   473    473     
   474    474       /* Extract the rowid or primary key for the current row */
   475    475       if( pPk ){
   476    476         for(i=0; i<nPk; i++){
   477    477           assert( pPk->aiColumn[i]>=0 );
   478         -        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
          478  +        sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iTabCur,
   479    479                                           pPk->aiColumn[i], iPk+i);
   480    480         }
   481    481         iKey = iPk;
   482    482       }else{
   483    483         iKey = ++pParse->nMem;
   484         -      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey);
          484  +      sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iTabCur, -1, iKey);
   485    485       }
   486    486     
   487    487       if( eOnePass!=ONEPASS_OFF ){
   488    488         /* For ONEPASS, no need to store the rowid/primary-key. There is only
   489    489         ** one, so just keep it in its register(s) and fall through to the
   490    490         ** delete code.  */
   491    491         nKey = nPk; /* OP_Found will use an unpacked key */
................................................................................
   733    733       /* Populate the OLD.* pseudo-table register array. These values will be 
   734    734       ** used by any BEFORE and AFTER triggers that exist.  */
   735    735       sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
   736    736       for(iCol=0; iCol<pTab->nCol; iCol++){
   737    737         testcase( mask!=0xffffffff && iCol==31 );
   738    738         testcase( mask!=0xffffffff && iCol==32 );
   739    739         if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
   740         -        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
          740  +        sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iDataCur, iCol,
          741  +                                        iOld+iCol+1);
   741    742         }
   742    743       }
   743    744   
   744    745       /* Invoke BEFORE DELETE trigger programs. */
   745    746       addrStart = sqlite3VdbeCurrentAddr(v);
   746    747       sqlite3CodeRowTrigger(pParse, pTrigger, 
   747    748           TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel

Changes to src/expr.c.

  3361   3361     if( iTabCol==XN_EXPR ){
  3362   3362       assert( pIdx->aColExpr );
  3363   3363       assert( pIdx->aColExpr->nExpr>iIdxCol );
  3364   3364       pParse->iSelfTab = iTabCur + 1;
  3365   3365       sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
  3366   3366       pParse->iSelfTab = 0;
  3367   3367     }else{
  3368         -    sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
         3368  +    sqlite3ExprCodeGetColumnOfTable(pParse, pIdx->pTable, iTabCur,
  3369   3369                                       iTabCol, regOut);
  3370   3370     }
  3371   3371   }
  3372   3372   
  3373   3373   /*
  3374   3374   ** Generate code to extract the value of the iCol-th column of a table.
  3375   3375   */
  3376   3376   void sqlite3ExprCodeGetColumnOfTable(
  3377         -  Vdbe *v,        /* The VDBE under construction */
         3377  +  Parse *pParse,  /* Parsing context */
  3378   3378     Table *pTab,    /* The table containing the value */
  3379   3379     int iTabCur,    /* The table cursor.  Or the PK cursor for WITHOUT ROWID */
  3380   3380     int iCol,       /* Index of the column to extract */
  3381   3381     int regOut      /* Extract the value into this register */
  3382   3382   ){
         3383  +  Vdbe *v = pParse->pVdbe;
         3384  +  assert( v!=0 );
  3383   3385     if( pTab==0 ){
  3384   3386       sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
  3385   3387       return;
  3386   3388     }
  3387   3389     if( iCol<0 || iCol==pTab->iPKey ){
  3388   3390       sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
  3389   3391     }else{
  3390         -    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
  3391         -    int x = iCol;
  3392         -    if( !HasRowid(pTab) && !IsVirtual(pTab) ){
         3392  +    int op;
         3393  +    int x;
         3394  +    if( IsVirtual(pTab) ){
         3395  +      op = OP_VColumn;
         3396  +      x = iCol;
         3397  +#ifndef SQLITE_OMIT_GENERATED_COLUMNS
         3398  +    }else if( pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL ){
         3399  +      int savedSelfTab = pParse->iSelfTab;
         3400  +      pParse->iSelfTab = iTabCur+1;
         3401  +      sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, iCol);
         3402  +      pParse->iSelfTab = savedSelfTab;
         3403  +      return;
         3404  +#endif
         3405  +    }else if( !HasRowid(pTab) ){
  3393   3406         x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
         3407  +      op = OP_Column;
         3408  +    }else{
         3409  +      x = sqlite3ColumnOfTable(pTab,iCol);
         3410  +      op = OP_Column;
  3394   3411       }
  3395   3412       sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
  3396   3413     }
  3397   3414     if( iCol>=0 ){
  3398   3415       sqlite3ColumnDefault(v, pTab, iCol, regOut);
  3399   3416     }
  3400   3417   }
................................................................................
  3410   3427     Parse *pParse,   /* Parsing and code generating context */
  3411   3428     Table *pTab,     /* Description of the table we are reading from */
  3412   3429     int iColumn,     /* Index of the table column */
  3413   3430     int iTable,      /* The cursor pointing to the table */
  3414   3431     int iReg,        /* Store results here */
  3415   3432     u8 p5            /* P5 value for OP_Column + FLAGS */
  3416   3433   ){
  3417         -  Vdbe *v = pParse->pVdbe;
  3418         -  assert( v!=0 );
  3419         -  sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
         3434  +  assert( pParse->pVdbe!=0 );
         3435  +  sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iTable, iColumn, iReg);
  3420   3436     if( p5 ){
  3421         -    sqlite3VdbeChangeP5(v, p5);
         3437  +    sqlite3VdbeChangeP5(pParse->pVdbe, p5);
  3422   3438     }
  3423   3439     return iReg;
  3424   3440   }
  3425   3441   
  3426   3442   /*
  3427   3443   ** Generate code to move content from registers iFrom...iFrom+nReg-1
  3428   3444   ** over to iTo..iTo+nReg-1.

Changes to src/parse.y.

   343    343   ccons ::= UNIQUE onconf(R).      {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
   344    344                                      SQLITE_IDXTYPE_UNIQUE);}
   345    345   ccons ::= CHECK LP expr(X) RP.   {sqlite3AddCheckConstraint(pParse,X);}
   346    346   ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
   347    347                                    {sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
   348    348   ccons ::= defer_subclause(D).    {sqlite3DeferForeignKey(pParse,D);}
   349    349   ccons ::= COLLATE ids(C).        {sqlite3AddCollateType(pParse, &C);}
          350  +ccons ::= GENERATED ALWAYS AS generated.
          351  +ccons ::= AS generated.
          352  +generated ::= LP expr(E) RP.
          353  +     {sqlite3AddGenerated(pParse,E,0);}
          354  +generated ::= LP expr(E) RP ID(TYPE).
          355  +     {sqlite3AddGenerated(pParse,E,&TYPE);}
   350    356   
   351    357   // The optional AUTOINCREMENT keyword
   352    358   %type autoinc {int}
   353    359   autoinc(X) ::= .          {X = 0;}
   354    360   autoinc(X) ::= AUTOINCR.  {X = 1;}
   355    361   
   356    362   // The next group of rules parses the arguments to a REFERENCES clause

Changes to src/pragma.c.

  1394   1394   
  1395   1395           /* Generate code to read the child key values into registers
  1396   1396           ** regRow..regRow+n. If any of the child key values are NULL, this 
  1397   1397           ** row cannot cause an FK violation. Jump directly to addrOk in 
  1398   1398           ** this case. */
  1399   1399           for(j=0; j<pFK->nCol; j++){
  1400   1400             int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
  1401         -          sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
         1401  +          sqlite3ExprCodeGetColumnOfTable(pParse, pTab, 0, iCol, regRow+j);
  1402   1402             sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
  1403   1403           }
  1404   1404   
  1405   1405           /* Generate code to query the parent index for a matching parent
  1406   1406           ** key. If a match is found, jump to addrOk. */
  1407   1407           if( pIdx ){
  1408   1408             sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
................................................................................
  1582   1582           }
  1583   1583           /* Verify that all NOT NULL columns really are NOT NULL */
  1584   1584           for(j=0; j<pTab->nCol; j++){
  1585   1585             char *zErr;
  1586   1586             int jmp2;
  1587   1587             if( j==pTab->iPKey ) continue;
  1588   1588             if( pTab->aCol[j].notNull==0 ) continue;
  1589         -          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
         1589  +          sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iDataCur, j, 3);
  1590   1590             sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
  1591   1591             jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
  1592   1592             zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
  1593   1593                                 pTab->aCol[j].zName);
  1594   1594             sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
  1595   1595             integrityCheckResultRow(v);
  1596   1596             sqlite3VdbeJumpHere(v, jmp2);

Changes to src/resolve.c.

   410    410   
   411    411       /*
   412    412       ** Perhaps the name is a reference to the ROWID
   413    413       */
   414    414       if( cnt==0
   415    415        && cntTab==1
   416    416        && pMatch
   417         -     && (pNC->ncFlags & NC_IdxExpr)==0
          417  +     && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
   418    418        && sqlite3IsRowid(zCol)
   419    419        && VisibleRowid(pMatch->pTab)
   420    420       ){
   421    421         cnt = 1;
   422    422         pExpr->iColumn = -1;
   423    423         pExpr->affExpr = SQLITE_AFF_INTEGER;
   424    424       }
................................................................................
   621    621   */
   622    622   static void notValid(
   623    623     Parse *pParse,       /* Leave error message here */
   624    624     NameContext *pNC,    /* The name context */
   625    625     const char *zMsg,    /* Type of error */
   626    626     int validMask        /* Set of contexts for which prohibited */
   627    627   ){
   628         -  assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
          628  +  assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 );
   629    629     if( (pNC->ncFlags & validMask)!=0 ){
   630    630       const char *zIn = "partial index WHERE clauses";
   631    631       if( pNC->ncFlags & NC_IdxExpr )      zIn = "index expressions";
   632    632   #ifndef SQLITE_OMIT_CHECK
   633    633       else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
   634    634   #endif
          635  +#ifndef SQLITE_OMIT_GENERATED_COLUMNS
          636  +    else if( pNC->ncFlags & NC_GenCol ) zIn = "GENERATED ALWAYS AS columns";
          637  +#endif
   635    638       sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
   636    639     }
   637    640   }
   638    641   
   639    642   /*
   640    643   ** Expression p should encode a floating point value between 1.0 and 0.0.
   641    644   ** Return 1024 times this value.  Or return -1 if p is not a floating point
................................................................................
   719    722   
   720    723         if( pExpr->op==TK_ID ){
   721    724           zDb = 0;
   722    725           zTable = 0;
   723    726           zColumn = pExpr->u.zToken;
   724    727         }else{
   725    728           Expr *pLeft = pExpr->pLeft;
   726         -        notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
          729  +        notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr|NC_GenCol);
   727    730           pRight = pExpr->pRight;
   728    731           if( pRight->op==TK_ID ){
   729    732             zDb = 0;
   730    733           }else{
   731    734             assert( pRight->op==TK_DOT );
   732    735             zDb = pLeft->u.zToken;
   733    736             pLeft = pRight->pLeft;
................................................................................
   816    819             ExprSetProperty(pExpr,EP_ConstFunc);
   817    820           }
   818    821           if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
   819    822             /* Date/time functions that use 'now', and other functions like
   820    823             ** sqlite_version() that might change over time cannot be used
   821    824             ** in an index. */
   822    825             notValid(pParse, pNC, "non-deterministic functions",
   823         -                   NC_IdxExpr|NC_PartIdx);
          826  +                   NC_IdxExpr|NC_PartIdx|NC_GenCol);
   824    827           }
   825    828           if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
   826    829            && pParse->nested==0
   827    830            && sqlite3Config.bInternalFunctions==0
   828    831           ){
   829    832             /* Internal-use-only functions are disallowed unless the
   830    833             ** SQL is being compiled using sqlite3NestedParse() */
................................................................................
   960    963       case TK_SELECT:
   961    964       case TK_EXISTS:  testcase( pExpr->op==TK_EXISTS );
   962    965   #endif
   963    966       case TK_IN: {
   964    967         testcase( pExpr->op==TK_IN );
   965    968         if( ExprHasProperty(pExpr, EP_xIsSelect) ){
   966    969           int nRef = pNC->nRef;
   967         -        notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
          970  +        notValid(pParse, pNC, "subqueries", 
          971  +                 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol);
   968    972           sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
   969    973           assert( pNC->nRef>=nRef );
   970    974           if( nRef!=pNC->nRef ){
   971    975             ExprSetProperty(pExpr, EP_VarSelect);
   972    976             pNC->ncFlags |= NC_VarSelect;
   973    977           }
   974    978         }
   975    979         break;
   976    980       }
   977    981       case TK_VARIABLE: {
   978         -      notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
          982  +      notValid(pParse, pNC, "parameters",
          983  +               NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol);
   979    984         break;
   980    985       }
   981    986       case TK_IS:
   982    987       case TK_ISNOT: {
   983    988         Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
   984    989         assert( !ExprHasProperty(pExpr, EP_Reduced) );
   985    990         /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
................................................................................
  1784   1789   ** Resolve names in expressions that can only reference a single table
  1785   1790   ** or which cannot reference any tables at all.  Examples:
  1786   1791   **
  1787   1792   **    (1)   CHECK constraints
  1788   1793   **    (2)   WHERE clauses on partial indices
  1789   1794   **    (3)   Expressions in indexes on expressions
  1790   1795   **    (4)   Expression arguments to VACUUM INTO.
         1796  +**    (5)   GENERATED ALWAYS as expressions
  1791   1797   **
  1792   1798   ** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
  1793   1799   ** nodes of the expression is set to -1 and the Expr.iColumn value is
  1794   1800   ** set to the column number.  In case (4), TK_COLUMN nodes cause an error.
  1795   1801   **
  1796   1802   ** Any errors cause an error message to be set in pParse.
  1797   1803   */
  1798   1804   int sqlite3ResolveSelfReference(
  1799         -  Parse *pParse,      /* Parsing context */
  1800         -  Table *pTab,        /* The table being referenced, or NULL */
  1801         -  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
  1802         -  Expr *pExpr,        /* Expression to resolve.  May be NULL. */
  1803         -  ExprList *pList     /* Expression list to resolve.  May be NULL. */
         1805  +  Parse *pParse,   /* Parsing context */
         1806  +  Table *pTab,     /* The table being referenced, or NULL */
         1807  +  int type,        /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */
         1808  +  Expr *pExpr,     /* Expression to resolve.  May be NULL. */
         1809  +  ExprList *pList  /* Expression list to resolve.  May be NULL. */
  1804   1810   ){
  1805   1811     SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
  1806   1812     NameContext sNC;                /* Name context for pParse->pNewTable */
  1807   1813     int rc;
  1808   1814   
  1809   1815     assert( type==0 || pTab!=0 );
  1810         -  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
         1816  +  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
         1817  +          || type==NC_GenCol || pTab==0 );
  1811   1818     memset(&sNC, 0, sizeof(sNC));
  1812   1819     memset(&sSrc, 0, sizeof(sSrc));
  1813   1820     if( pTab ){
  1814   1821       sSrc.nSrc = 1;
  1815   1822       sSrc.a[0].zName = pTab->zName;
  1816   1823       sSrc.a[0].pTab = pTab;
  1817   1824       sSrc.a[0].iCursor = -1;

Changes to src/select.c.

  6413   6413           regBase = sqlite3GetTempRange(pParse, nCol);
  6414   6414           sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
  6415   6415           j = nGroupBy;
  6416   6416           for(i=0; i<sAggInfo.nColumn; i++){
  6417   6417             struct AggInfo_col *pCol = &sAggInfo.aCol[i];
  6418   6418             if( pCol->iSorterColumn>=j ){
  6419   6419               int r1 = j + regBase;
  6420         -            sqlite3ExprCodeGetColumnOfTable(v,
         6420  +            sqlite3ExprCodeGetColumnOfTable(pParse,
  6421   6421                                  pCol->pTab, pCol->iTable, pCol->iColumn, r1);
  6422   6422               j++;
  6423   6423             }
  6424   6424           }
  6425   6425           regRecord = sqlite3GetTempReg(pParse);
  6426   6426           sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
  6427   6427           sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord);

Changes to src/sqliteInt.h.

  1819   1819   
  1820   1820   /*
  1821   1821   ** information about each column of an SQL table is held in an instance
  1822   1822   ** of this structure.
  1823   1823   */
  1824   1824   struct Column {
  1825   1825     char *zName;     /* Name of this column, \000, then the type */
  1826         -  Expr *pDflt;     /* Default value of this column */
         1826  +  Expr *pDflt;     /* Default value or GENERATED ALWAYS AS value */
  1827   1827     char *zColl;     /* Collating sequence.  If NULL, use the default */
  1828   1828     u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  1829   1829     char affinity;   /* One of the SQLITE_AFF_... values */
  1830   1830     u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
  1831   1831     u8 colFlags;     /* Boolean properties.  See COLFLAG_ defines below */
  1832   1832   };
  1833   1833   
  1834   1834   /* Allowed values for Column.colFlags:
  1835   1835   */
  1836         -#define COLFLAG_PRIMKEY  0x0001    /* Column is part of the primary key */
  1837         -#define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
  1838         -#define COLFLAG_HASTYPE  0x0004    /* Type name follows column name */
  1839         -#define COLFLAG_UNIQUE   0x0008    /* Column def contains "UNIQUE" or "PK" */
         1836  +#define COLFLAG_PRIMKEY   0x0001   /* Column is part of the primary key */
         1837  +#define COLFLAG_HIDDEN    0x0002   /* A hidden column in a virtual table */
         1838  +#define COLFLAG_HASTYPE   0x0004   /* Type name follows column name */
         1839  +#define COLFLAG_UNIQUE    0x0008   /* Column def contains "UNIQUE" or "PK" */
  1840   1840   #define COLFLAG_SORTERREF 0x0010   /* Use sorter-refs with this column */
         1841  +#define COLFLAG_VIRTUAL   0x0020   /* GENERATED ALWAYS AS ... VIRTUAL */
         1842  +#define COLFLAG_STORED    0x0040   /* GENERATED ALWAYS AS ... STORED */
  1841   1843   
  1842   1844   /*
  1843   1845   ** A "Collating Sequence" is defined by an instance of the following
  1844   1846   ** structure. Conceptually, a collating sequence consists of a name and
  1845   1847   ** a comparison routine that defines the order of that sequence.
  1846   1848   **
  1847   1849   ** If CollSeq.xCmp is NULL, it means that the
................................................................................
  1973   1975     ExprList *pCheck;    /* All CHECK constraints */
  1974   1976                          /*   ... also used as column name list in a VIEW */
  1975   1977     int tnum;            /* Root BTree page for this table */
  1976   1978     u32 nTabRef;         /* Number of pointers to this Table */
  1977   1979     u32 tabFlags;        /* Mask of TF_* values */
  1978   1980     i16 iPKey;           /* If not negative, use aCol[iPKey] as the rowid */
  1979   1981     i16 nCol;            /* Number of columns in this table */
         1982  +  i16 nVCol;           /* Number of virtual columns */
  1980   1983     LogEst nRowLogEst;   /* Estimated rows in table - from sqlite_stat1 table */
  1981   1984     LogEst szTabRow;     /* Estimated size of each table row in bytes */
  1982   1985   #ifdef SQLITE_ENABLE_COSTMULT
  1983   1986     LogEst costMult;     /* Cost multiplier for using this table */
  1984   1987   #endif
  1985   1988     u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
  1986   1989   #ifndef SQLITE_OMIT_ALTERTABLE
................................................................................
  2804   2807   **
  2805   2808   ** Value constraints (all checked via assert()):
  2806   2809   **    NC_HasAgg    == SF_HasAgg    == EP_Agg
  2807   2810   **    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
  2808   2811   **    NC_HasWin    == EP_Win
  2809   2812   **
  2810   2813   */
  2811         -#define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
  2812         -#define NC_PartIdx   0x0002  /* True if resolving a partial index WHERE */
  2813         -#define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
  2814         -#define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
  2815         -#define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
  2816         -#define NC_IdxExpr   0x0020  /* True if resolving columns of CREATE INDEX */
  2817         -#define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
  2818         -#define NC_UEList    0x0080  /* True if uNC.pEList is used */
  2819         -#define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
  2820         -#define NC_UUpsert   0x0200  /* True if uNC.pUpsert is used */
  2821         -#define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
  2822         -#define NC_Complex   0x2000  /* True if a function or subquery seen */
  2823         -#define NC_AllowWin  0x4000  /* Window functions are allowed here */
  2824         -#define NC_HasWin    0x8000  /* One or more window functions seen */
  2825         -#define NC_IsDDL    0x10000  /* Resolving names in a CREATE statement */
         2814  +#define NC_AllowAgg  0x00001  /* Aggregate functions are allowed here */
         2815  +#define NC_PartIdx   0x00002  /* True if resolving a partial index WHERE */
         2816  +#define NC_IsCheck   0x00004  /* True if resolving a CHECK constraint */
         2817  +#define NC_InAggFunc 0x00008  /* True if analyzing arguments to an agg func */
         2818  +#define NC_HasAgg    0x00010  /* One or more aggregate functions seen */
         2819  +#define NC_IdxExpr   0x00020  /* True if resolving columns of CREATE INDEX */
         2820  +#define NC_VarSelect 0x00040  /* A correlated subquery has been seen */
         2821  +#define NC_UEList    0x00080  /* True if uNC.pEList is used */
         2822  +#define NC_UAggInfo  0x00100  /* True if uNC.pAggInfo is used */
         2823  +#define NC_UUpsert   0x00200  /* True if uNC.pUpsert is used */
         2824  +#define NC_MinMaxAgg 0x01000  /* min/max aggregates seen.  See note above */
         2825  +#define NC_Complex   0x02000  /* True if a function or subquery seen */
         2826  +#define NC_AllowWin  0x04000  /* Window functions are allowed here */
         2827  +#define NC_HasWin    0x08000  /* One or more window functions seen */
         2828  +#define NC_IsDDL     0x10000  /* Resolving names in a CREATE statement */
         2829  +#define NC_GenCol    0x20000  /* True for a GENERATED ALWAYS AS clause */
  2826   2830   
  2827   2831   /*
  2828   2832   ** An instance of the following object describes a single ON CONFLICT
  2829   2833   ** clause in an upsert.
  2830   2834   **
  2831   2835   ** The pUpsertTarget field is only set if the ON CONFLICT clause includes
  2832   2836   ** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
................................................................................
  3934   3938   void sqlite3DeleteColumnNames(sqlite3*,Table*);
  3935   3939   int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
  3936   3940   void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
  3937   3941   Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
  3938   3942   void sqlite3OpenMasterTable(Parse *, int);
  3939   3943   Index *sqlite3PrimaryKeyIndex(Table*);
  3940   3944   i16 sqlite3ColumnOfIndex(Index*, i16);
         3945  +#ifdef SQLITE_OMIT_GENERATED_COLUMNS
         3946  +# define sqlite3ColumnOfTable(T,X) (X)  /* No-op pass-through */
         3947  +#else
         3948  +  i16 sqlite3ColumnOfTable(Table*, i16);
         3949  +#endif
  3941   3950   void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
  3942   3951   #if SQLITE_ENABLE_HIDDEN_COLUMNS
  3943   3952     void sqlite3ColumnPropertiesFromName(Table*, Column*);
  3944   3953   #else
  3945   3954   # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
  3946   3955   #endif
  3947   3956   void sqlite3AddColumn(Parse*,Token*,Token*);
  3948   3957   void sqlite3AddNotNull(Parse*, int);
  3949   3958   void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
  3950   3959   void sqlite3AddCheckConstraint(Parse*, Expr*);
  3951   3960   void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
  3952   3961   void sqlite3AddCollateType(Parse*, Token*);
         3962  +void sqlite3AddGenerated(Parse*,Expr*,Token*);
  3953   3963   void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
  3954   3964   int sqlite3ParseUri(const char*,const char*,unsigned int*,
  3955   3965                       sqlite3_vfs**,char**,char **);
  3956   3966   #ifdef SQLITE_HAS_CODEC
  3957   3967     int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
  3958   3968   #else
  3959   3969   # define sqlite3CodecQueryParameters(A,B,C) 0
................................................................................
  4049   4059   int sqlite3WhereBreakLabel(WhereInfo*);
  4050   4060   int sqlite3WhereOkOnePass(WhereInfo*, int*);
  4051   4061   #define ONEPASS_OFF      0        /* Use of ONEPASS not allowed */
  4052   4062   #define ONEPASS_SINGLE   1        /* ONEPASS valid for a single row update */
  4053   4063   #define ONEPASS_MULTI    2        /* ONEPASS is valid for multiple rows */
  4054   4064   void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
  4055   4065   int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
  4056         -void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
         4066  +void sqlite3ExprCodeGetColumnOfTable(Parse*, Table*, int, int, int);
  4057   4067   void sqlite3ExprCodeMove(Parse*, int, int, int);
  4058   4068   void sqlite3ExprCode(Parse*, Expr*, int);
  4059   4069   void sqlite3ExprCodeCopy(Parse*, Expr*, int);
  4060   4070   void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
  4061   4071   int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
  4062   4072   int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
  4063   4073   int sqlite3ExprCodeTarget(Parse*, Expr*, int);

Changes to src/update.c.

   538    538       /* Read the PK of the current row into an array of registers. In
   539    539       ** ONEPASS_OFF mode, serialize the array into a record and store it in
   540    540       ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
   541    541       ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table 
   542    542       ** is not required) and leave the PK fields in the array of registers.  */
   543    543       for(i=0; i<nPk; i++){
   544    544         assert( pPk->aiColumn[i]>=0 );
   545         -      sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
          545  +      sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iDataCur,
          546  +                                      pPk->aiColumn[i], iPk+i);
   546    547       }
   547    548       if( eOnePass ){
   548    549         if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen);
   549    550         nKey = nPk;
   550    551         regKey = iPk;
   551    552       }else{
   552    553         sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
................................................................................
   624    625       );
   625    626       for(i=0; i<pTab->nCol; i++){
   626    627         if( oldmask==0xffffffff
   627    628          || (i<32 && (oldmask & MASKBIT32(i))!=0)
   628    629          || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
   629    630         ){
   630    631           testcase(  oldmask!=0xffffffff && i==31 );
   631         -        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
          632  +        sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iDataCur, i, regOld+i);
   632    633         }else{
   633    634           sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
   634    635         }
   635    636       }
   636    637       if( chngRowid==0 && pPk==0 ){
   637    638         sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
   638    639       }
................................................................................
   665    666           /* This branch loads the value of a column that will not be changed 
   666    667           ** into a register. This is done if there are no BEFORE triggers, or
   667    668           ** if there are one or more BEFORE triggers that use this value via
   668    669           ** a new.* reference in a trigger program.
   669    670           */
   670    671           testcase( i==31 );
   671    672           testcase( i==32 );
   672         -        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
          673  +        sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iDataCur, i, regNew+i);
   673    674         }else{
   674    675           sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
   675    676         }
   676    677       }
   677    678     }
   678    679   
   679    680     /* Fire any BEFORE UPDATE triggers. This happens before constraints are
................................................................................
   705    706       ** in case this has happened. Only unmodified columns are reloaded.
   706    707       ** The values computed for modified columns use the values before the
   707    708       ** BEFORE trigger runs.  See test case trigger1-18.0 (added 2018-04-26)
   708    709       ** for an example.
   709    710       */
   710    711       for(i=0; i<pTab->nCol; i++){
   711    712         if( aXRef[i]<0 && i!=pTab->iPKey ){
   712         -        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
          713  +        sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iDataCur, i, regNew+i);
   713    714         }
   714    715       }
   715    716     }
   716    717   
   717    718     if( !isView ){
   718    719       /* Do constraint checks. */
   719    720       assert( regOldRowid>0 );

Changes to src/wherecode.c.

  2068   2068             ** duplicate rows from prior sub-WHERE clauses, and record the
  2069   2069             ** rowid (or PRIMARY KEY) for the current row so that the same
  2070   2070             ** row will be skipped in subsequent sub-WHERE clauses.
  2071   2071             */
  2072   2072             if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
  2073   2073               int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
  2074   2074               if( HasRowid(pTab) ){
  2075         -              sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid);
         2075  +              sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iCur, -1, regRowid);
  2076   2076                 jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
  2077   2077                                             regRowid, iSet);
  2078   2078                 VdbeCoverage(v);
  2079   2079               }else{
  2080   2080                 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
  2081   2081                 int nPk = pPk->nKeyCol;
  2082   2082                 int iPk;
  2083   2083                 int r;
  2084   2084   
  2085   2085                 /* Read the PK into an array of temp registers. */
  2086   2086                 r = sqlite3GetTempRange(pParse, nPk);
  2087   2087                 for(iPk=0; iPk<nPk; iPk++){
  2088   2088                   int iCol = pPk->aiColumn[iPk];
  2089         -                sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk);
         2089  +                sqlite3ExprCodeGetColumnOfTable(pParse, pTab, iCur, iCol,r+iPk);
  2090   2090                 }
  2091   2091   
  2092   2092                 /* Check if the temp table already contains this key. If so,
  2093   2093                 ** the row has already been included in the result set and
  2094   2094                 ** can be ignored (by jumping past the Gosub below). Otherwise,
  2095   2095                 ** insert the key into the temp table and proceed with processing
  2096   2096                 ** the row.

Changes to tool/mkkeywordhash.c.

   160    160   static Keyword aKeywordTable[] = {
   161    161     { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
   162    162     { "ACTION",           "TK_ACTION",       FKEY                   },
   163    163     { "ADD",              "TK_ADD",          ALTER                  },
   164    164     { "AFTER",            "TK_AFTER",        TRIGGER                },
   165    165     { "ALL",              "TK_ALL",          ALWAYS                 },
   166    166     { "ALTER",            "TK_ALTER",        ALTER                  },
          167  +  { "ALWAYS",           "TK_ALWAYS",       ALWAYS                 },
   167    168     { "ANALYZE",          "TK_ANALYZE",      ANALYZE                },
   168    169     { "AND",              "TK_AND",          ALWAYS                 },
   169    170     { "AS",               "TK_AS",           ALWAYS                 },
   170    171     { "ASC",              "TK_ASC",          ALWAYS                 },
   171    172     { "ATTACH",           "TK_ATTACH",       ATTACH                 },
   172    173     { "AUTOINCREMENT",    "TK_AUTOINCR",     AUTOINCR               },
   173    174     { "BEFORE",           "TK_BEFORE",       TRIGGER                },
................................................................................
   212    213     { "FILTER",           "TK_FILTER",       WINDOWFUNC             },
   213    214     { "FIRST",            "TK_FIRST",        ALWAYS                 },
   214    215     { "FOLLOWING",        "TK_FOLLOWING",    WINDOWFUNC             },
   215    216     { "FOR",              "TK_FOR",          TRIGGER                },
   216    217     { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
   217    218     { "FROM",             "TK_FROM",         ALWAYS                 },
   218    219     { "FULL",             "TK_JOIN_KW",      ALWAYS                 },
          220  +  { "GENERATED",        "TK_GENERATED",    ALWAYS                 },
   219    221     { "GLOB",             "TK_LIKE_KW",      ALWAYS                 },
   220    222     { "GROUP",            "TK_GROUP",        ALWAYS                 },
   221    223     { "GROUPS",           "TK_GROUPS",       WINDOWFUNC             },
   222    224     { "HAVING",           "TK_HAVING",       ALWAYS                 },
   223    225     { "IF",               "TK_IF",           ALWAYS                 },
   224    226     { "IGNORE",           "TK_IGNORE",       CONFLICT|TRIGGER       },
   225    227     { "IMMEDIATE",        "TK_IMMEDIATE",    ALWAYS                 },