/ Check-in [27ab41c9]
Login

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

Overview
Comment:Refactor names of column index transformation functions, for clarity. Get generated columns working with ALTER TABLE RENAME COLUMN.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | generated-columns
Files: files | file ages | folders
SHA3-256: 27ab41c9102e7801ff829488fc123a8040da008bef373d6704efbe2f93e1da90
User & Date: drh 2019-10-19 13:29:10
Context
2019-10-19
15:01
Add testcase macros. check-in: fb9c9bb2 user: drh tags: generated-columns
13:29
Refactor names of column index transformation functions, for clarity. Get generated columns working with ALTER TABLE RENAME COLUMN. check-in: 27ab41c9 user: drh tags: generated-columns
2019-10-18
18:33
Fixes for WITHOUT ROWID tables with VIRTUAL columns and an INTEGER PRIMARY KEY. check-in: 86074da0 user: drh tags: generated-columns
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/alter.c.

1330
1331
1332
1333
1334
1335
1336





1337
1338
1339
1340
1341
1342
1343
        for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
        }
        for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
        }
      }






      for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
        for(i=0; i<pFKey->nCol; i++){
          if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
            renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
          }
          if( 0==sqlite3_stricmp(pFKey->zTo, zTable)







>
>
>
>
>







1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
        for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
        }
        for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
        }
      }
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
      for(i=0; i<sParse.pNewTable->nCol; i++){
        sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt);
      }
#endif

      for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
        for(i=0; i<pFKey->nCol; i++){
          if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
            renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
          }
          if( 0==sqlite3_stricmp(pFKey->zTo, zTable)

Changes to src/analyze.c.

1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
    }else{
      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
      int j, k, regKey;
      regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
      for(j=0; j<pPk->nKeyCol; j++){
        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
        assert( k>=0 && k<pIdx->nColumn );
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
        VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
      }
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
      sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
    }







|







1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
    }else{
      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
      int j, k, regKey;
      regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
      for(j=0; j<pPk->nKeyCol; j++){
        k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
        assert( k>=0 && k<pIdx->nColumn );
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
        VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
      }
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
      sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
    }

Changes to src/build.c.

873
874
875
876
877
878
879
880
881


882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
....
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584




1585
1586
1587
1588
1589
1590
1591
....
1593
1594
1595
1596
1597
1598
1599
1600

1601
1602
1603
1604
1605
1606
1607
....
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
Index *sqlite3PrimaryKeyIndex(Table *pTab){
  Index *p;
  for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){}
  return p;
}

/*
** Return the true column number of index pIdx that corresponds to table
** true column iCol.  Return -1 if not found.


*/
i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
  int i;
  for(i=0; i<pIdx->nColumn; i++){
    if( iCol==pIdx->aiColumn[i] ) return i;
  }
  return -1;
}

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Convert a storage column number into a true column number.
**
** The storage column number (0,1,2,....) is the index of the value
** as it appears in the record on disk.  The true column number
** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
**
** The storage column number is less than the true column number if
** and only there are virtual columns to the left.
**
** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
**
** This function is the inverse of sqlite3ColumnOfTable().
*/
i16 sqlite3ColumnOfStorage(Table *pTab, i16 iCol){
  if( pTab->tabFlags & TF_HasVirtual ){
    int i;
    for(i=0; i<=iCol; i++){
      if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++;
    }
  }
  return iCol;
}
#endif

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Convert a true column number into a storage column number.
**
** The storage column number (0,1,2,....) is the index of the value
** as it appears in the record on disk.  The true column number
** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
**
** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
**
** This function is the inverse of sqlite3ColumnOfStorage().
*/
i16 sqlite3ColumnOfTable(Table *pTab, i16 iCol){
  int i;
  i16 n;
  assert( iCol<pTab->nCol );
  if( (pTab->tabFlags & TF_HasVirtual)==0 ) return iCol;
  for(i=0, n=0; i<iCol; i++){
    if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
  }
................................................................................
** column.
*/
void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  u8 eType = COLFLAG_VIRTUAL;
  Table *pTab = pParse->pNewTable;
  Column *pCol;
  if( IN_RENAME_OBJECT ){
    sqlite3RenameExprUnmap(pParse, pExpr);
  }
  if( pTab==0 ) goto generated_done;
  pCol = &(pTab->aCol[pTab->nCol-1]);




  if( pCol->pDflt ) goto generated_error;
  if( pType ){
    if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
      /* no-op */
    }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
      eType = COLFLAG_STORED;
    }else{
................................................................................
    }
  }
  if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--;
  pCol->colFlags |= eType;
  assert( TF_HasVirtual==COLFLAG_VIRTUAL );
  assert( TF_HasStored==COLFLAG_STORED );
  pTab->tabFlags |= eType;
  pCol->pDflt = sqlite3ExprDup(pParse->db, pExpr, 0);

  goto generated_done;

generated_error:
  sqlite3ErrorMsg(pParse, "incorrect GENERATED ALWAYS AS on column \"%s\"",
                  pCol->zName);
generated_done:
  sqlite3ExprDelete(pParse->db, pExpr);
................................................................................
  }
  sqlite3DefaultRowEst(pIndex);
  if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);

  /* If this index contains every column of its table, then mark
  ** it as a covering index */
  assert( HasRowid(pTab) 
      || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
  recomputeColumnsNotIndexed(pIndex);
  if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
    pIndex->isCovering = 1;
    for(j=0; j<pTab->nCol; j++){
      if( j==pTab->iPKey ) continue;
      if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
      pIndex->isCovering = 0;
      break;
    }
  }

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a







|
|
>
>

|








|





|
|



|

|











|







|

|







 







<
<
<


>
>
>
>







 







|
>







 







|





|







873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
....
1575
1576
1577
1578
1579
1580
1581



1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
....
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
....
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
Index *sqlite3PrimaryKeyIndex(Table *pTab){
  Index *p;
  for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){}
  return p;
}

/*
** Convert an table column number into a index column number.  That is,
** for the column iCol in the table (as defined by the CREATE TABLE statement)
** find the (first) offset of that column in index pIdx.  Or return -1
** if column iCol is not used in index pIdx.
*/
i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){
  int i;
  for(i=0; i<pIdx->nColumn; i++){
    if( iCol==pIdx->aiColumn[i] ) return i;
  }
  return -1;
}

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Convert a storage column number into a table column number.
**
** The storage column number (0,1,2,....) is the index of the value
** as it appears in the record on disk.  The true column number
** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
**
** The storage column number is less than the table column number if
** and only there are VIRTUAL columns to the left.
**
** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
**
** This function is the inverse of sqlite3TableColumnToStorage().
*/
i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){
  if( pTab->tabFlags & TF_HasVirtual ){
    int i;
    for(i=0; i<=iCol; i++){
      if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++;
    }
  }
  return iCol;
}
#endif

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Convert a table column number into a storage column number.
**
** The storage column number (0,1,2,....) is the index of the value
** as it appears in the record on disk.  The true column number
** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
**
** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
**
** This function is the inverse of sqlite3StorageColumnToTable().
*/
i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
  int i;
  i16 n;
  assert( iCol<pTab->nCol );
  if( (pTab->tabFlags & TF_HasVirtual)==0 ) return iCol;
  for(i=0, n=0; i<iCol; i++){
    if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
  }
................................................................................
** column.
*/
void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
  u8 eType = COLFLAG_VIRTUAL;
  Table *pTab = pParse->pNewTable;
  Column *pCol;



  if( pTab==0 ) goto generated_done;
  pCol = &(pTab->aCol[pTab->nCol-1]);
  if( IN_DECLARE_VTAB ){
    sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns");
    goto generated_done;
  }
  if( pCol->pDflt ) goto generated_error;
  if( pType ){
    if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
      /* no-op */
    }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
      eType = COLFLAG_STORED;
    }else{
................................................................................
    }
  }
  if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--;
  pCol->colFlags |= eType;
  assert( TF_HasVirtual==COLFLAG_VIRTUAL );
  assert( TF_HasStored==COLFLAG_STORED );
  pTab->tabFlags |= eType;
  pCol->pDflt = pExpr;
  pExpr = 0;
  goto generated_done;

generated_error:
  sqlite3ErrorMsg(pParse, "incorrect GENERATED ALWAYS AS on column \"%s\"",
                  pCol->zName);
generated_done:
  sqlite3ExprDelete(pParse->db, pExpr);
................................................................................
  }
  sqlite3DefaultRowEst(pIndex);
  if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);

  /* If this index contains every column of its table, then mark
  ** it as a covering index */
  assert( HasRowid(pTab) 
      || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 );
  recomputeColumnsNotIndexed(pIndex);
  if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
    pIndex->isCovering = 1;
    for(j=0; j<pTab->nCol; j++){
      if( j==pTab->iPKey ) continue;
      if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue;
      pIndex->isCovering = 0;
      break;
    }
  }

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a

Changes to src/expr.c.

3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
....
3587
3588
3589
3590
3591
3592
3593

3594
3595
3596
3597
3598
3599
3600
3601
....
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
        sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, regOut);
        pParse->iSelfTab = savedSelfTab;
        pCol->colFlags &= ~COLFLAG_BUSY;
      }
      return;
#endif
    }else if( !HasRowid(pTab) ){
      x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
      op = OP_Column;
    }else{
      x = sqlite3ColumnOfTable(pTab,iCol);
      op = OP_Column;
    }
    sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
    sqlite3ColumnDefault(v, pTab, iCol, regOut);
  }
}

................................................................................
          assert( pTab!=0 );
          assert( pExpr->iColumn>=XN_ROWID );
          assert( pExpr->iColumn<pExpr->y.pTab->nCol );
          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;
            }
................................................................................
** Check to see if there are references to columns in table 
** pWalker->u.pIdxCover->iCur can be satisfied using the index
** pWalker->u.pIdxCover->pIdx.
*/
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pWalker->u.pIdxCover->iCur
   && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
  ){
    pWalker->eCode = 1;
    return WRC_Abort;
  }
  return WRC_Continue;
}








|


|







 







>
|







 







|







3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
....
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
....
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
        sqlite3ExprCode(pParse, pTab->aCol[iCol].pDflt, regOut);
        pParse->iSelfTab = savedSelfTab;
        pCol->colFlags &= ~COLFLAG_BUSY;
      }
      return;
#endif
    }else if( !HasRowid(pTab) ){
      x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
      op = OP_Column;
    }else{
      x = sqlite3TableColumnToStorage(pTab,iCol);
      op = OP_Column;
    }
    sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
    sqlite3ColumnDefault(v, pTab, iCol, regOut);
  }
}

................................................................................
          assert( pTab!=0 );
          assert( pExpr->iColumn>=XN_ROWID );
          assert( pExpr->iColumn<pExpr->y.pTab->nCol );
          if( pExpr->iColumn<0 ){
            return -1-pParse->iSelfTab;
          }
          pCol = pTab->aCol + pExpr->iColumn;
          iSrc = sqlite3TableColumnToStorage(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;
            }
................................................................................
** Check to see if there are references to columns in table 
** pWalker->u.pIdxCover->iCur can be satisfied using the index
** pWalker->u.pIdxCover->pIdx.
*/
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pWalker->u.pIdxCover->iCur
   && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
  ){
    pWalker->eCode = 1;
    return WRC_Abort;
  }
  return WRC_Continue;
}

Changes to src/insert.c.

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
....
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
....
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
....
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
    */
    nHidden = 0;
    iRegStore = regRowid+1;
    for(i=0; i<pTab->nCol; i++, iRegStore++){
      int k;
      u32 colFlags;
      assert( i>=nHidden );
      assert( iRegStore==sqlite3ColumnOfTable(pTab,i)+regRowid+1 );
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the rowid will be substituted
        ** in its place.  Hence, fill this column with a NULL to avoid
        ** taking up data space with information that will never be used.
        ** As there may be shallow copies of this value, make it a soft-NULL */
        sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
................................................................................
      iReg = ++pParse->nMem;
      assert( pParse->iSelfTab==0 );
      pParse->iSelfTab = -regNewData;
      sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iReg);
      pParse->iSelfTab = 0;
      if( onError==OE_Replace ) onError = OE_Abort;
    }else{
      iReg = sqlite3ColumnOfTable(pTab, i) + regNewData + 1;
    }
    switch( onError ){
      case OE_Replace: {
        assert( onError==OE_Replace );
        addr1 = sqlite3VdbeMakeLabel(pParse);
        sqlite3VdbeAddOp2(v, OP_NotNull, iReg, addr1);
          VdbeCoverage(v);
................................................................................
      }else if( pTab->aCol[iField].colFlags & COLFLAG_VIRTUAL ){
        pParse->iSelfTab = -(regNewData+1);
        sqlite3ExprCodeCopy(pParse, pTab->aCol[iField].pDflt, regIdx+i);
        pParse->iSelfTab = 0;
        VdbeComment((v, "%s column %d", pIdx->zName, i));
#endif
      }else{
        x = sqlite3ColumnOfTable(pTab, iField) + regNewData + 1;
        sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
        VdbeComment((v, "%s", pTab->aCol[iField].zName));
      }
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
    VdbeComment((v, "for %s", pIdx->zName));
#ifdef SQLITE_ENABLE_NULL_TRIM
................................................................................
      }else{
        int x;
        /* Extract the PRIMARY KEY from the end of the index entry and
        ** store it in registers regR..regR+nPk-1 */
        if( pIdx!=pPk ){
          for(i=0; i<pPk->nKeyCol; i++){
            assert( pPk->aiColumn[i]>=0 );
            x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
            sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
            VdbeComment((v, "%s.%s", pTab->zName,
                         pTab->aCol[pPk->aiColumn[i]].zName));
          }
        }
        if( isUpdate ){
          /* If currently processing the PRIMARY KEY of a WITHOUT ROWID 







|







 







|







 







|







 







|







1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
....
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
....
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
....
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
    */
    nHidden = 0;
    iRegStore = regRowid+1;
    for(i=0; i<pTab->nCol; i++, iRegStore++){
      int k;
      u32 colFlags;
      assert( i>=nHidden );
      assert( iRegStore==sqlite3TableColumnToStorage(pTab,i)+regRowid+1 );
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the rowid will be substituted
        ** in its place.  Hence, fill this column with a NULL to avoid
        ** taking up data space with information that will never be used.
        ** As there may be shallow copies of this value, make it a soft-NULL */
        sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
................................................................................
      iReg = ++pParse->nMem;
      assert( pParse->iSelfTab==0 );
      pParse->iSelfTab = -regNewData;
      sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iReg);
      pParse->iSelfTab = 0;
      if( onError==OE_Replace ) onError = OE_Abort;
    }else{
      iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1;
    }
    switch( onError ){
      case OE_Replace: {
        assert( onError==OE_Replace );
        addr1 = sqlite3VdbeMakeLabel(pParse);
        sqlite3VdbeAddOp2(v, OP_NotNull, iReg, addr1);
          VdbeCoverage(v);
................................................................................
      }else if( pTab->aCol[iField].colFlags & COLFLAG_VIRTUAL ){
        pParse->iSelfTab = -(regNewData+1);
        sqlite3ExprCodeCopy(pParse, pTab->aCol[iField].pDflt, regIdx+i);
        pParse->iSelfTab = 0;
        VdbeComment((v, "%s column %d", pIdx->zName, i));
#endif
      }else{
        x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1;
        sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
        VdbeComment((v, "%s", pTab->aCol[iField].zName));
      }
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
    VdbeComment((v, "for %s", pIdx->zName));
#ifdef SQLITE_ENABLE_NULL_TRIM
................................................................................
      }else{
        int x;
        /* Extract the PRIMARY KEY from the end of the index entry and
        ** store it in registers regR..regR+nPk-1 */
        if( pIdx!=pPk ){
          for(i=0; i<pPk->nKeyCol; i++){
            assert( pPk->aiColumn[i]>=0 );
            x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]);
            sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
            VdbeComment((v, "%s.%s", pTab->zName,
                         pTab->aCol[pPk->aiColumn[i]].zName));
          }
        }
        if( isUpdate ){
          /* If currently processing the PRIMARY KEY of a WITHOUT ROWID 

Changes to src/sqliteInt.h.

1814
1815
1816
1817
1818
1819
1820
1821
1822













1823
1824
1825
1826
1827
1828
1829
....
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
  int nRefModule;                      /* Number of pointers to this object */
  void *pAux;                          /* pAux passed to create_module() */
  void (*xDestroy)(void *);            /* Module destructor function */
  Table *pEpoTab;                      /* Eponymous table for this module */
};

/*
** information about each column of an SQL table is held in an instance
** of this structure.













*/
struct Column {
  char *zName;     /* Name of this column, \000, then the type */
  Expr *pDflt;     /* Default value or GENERATED ALWAYS AS value */
  char *zColl;     /* Collating sequence.  If NULL, use the default */
  u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  char affinity;   /* One of the SQLITE_AFF_... values */
................................................................................
void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
void sqlite3OpenMasterTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*);
i16 sqlite3ColumnOfIndex(Index*, i16);
#ifdef SQLITE_OMIT_GENERATED_COLUMNS
# define sqlite3ColumnOfTable(T,X)   (X)  /* No-op pass-through */
# define sqlite3ColumnOfStorage(T,X) (X)  /* No-op pass-through */
#else
  i16 sqlite3ColumnOfTable(Table*, i16);
  i16 sqlite3ColumnOfStorage(Table*, i16);
#endif
void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
#if SQLITE_ENABLE_HIDDEN_COLUMNS
  void sqlite3ColumnPropertiesFromName(Table*, Column*);
#else
# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
#endif







|
|
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|

|
|

|
|







1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
....
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
  int nRefModule;                      /* Number of pointers to this object */
  void *pAux;                          /* pAux passed to create_module() */
  void (*xDestroy)(void *);            /* Module destructor function */
  Table *pEpoTab;                      /* Eponymous table for this module */
};

/*
** Information about each column of an SQL table is held in an instance
** of the Column structure, in the Table.aCol[] array.
**
** Definitions:
**
**   "table column index"     This is the index of the column in the
**                            Table.aCol[] array, and also the index of
**                            the column in the original CREATE TABLE stmt.
**
**   "storage column index"   This is the index of the column in the
**                            record BLOB generated by the OP_MakeRecord
**                            opcode.  The storage column index is less than
**                            or equal to the table column index.  It is
**                            equal if and only if there are no VIRTUAL
**                            columns to the left.
*/
struct Column {
  char *zName;     /* Name of this column, \000, then the type */
  Expr *pDflt;     /* Default value or GENERATED ALWAYS AS value */
  char *zColl;     /* Collating sequence.  If NULL, use the default */
  u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  char affinity;   /* One of the SQLITE_AFF_... values */
................................................................................
void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
void sqlite3OpenMasterTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*);
i16 sqlite3TableColumnToIndex(Index*, i16);
#ifdef SQLITE_OMIT_GENERATED_COLUMNS
# define sqlite3TableColumnToStorage(T,X) (X)  /* No-op pass-through */
# define sqlite3StorageColumnToTable(T,X) (X)  /* No-op pass-through */
#else
  i16 sqlite3TableColumnToStorage(Table*, i16);
  i16 sqlite3StorageColumnToTable(Table*, i16);
#endif
void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
#if SQLITE_ENABLE_HIDDEN_COLUMNS
  void sqlite3ColumnPropertiesFromName(Table*, Column*);
#else
# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
#endif

Changes to src/upsert.c.

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
      int nPk = pPk->nKeyCol;
      int iPk = pParse->nMem+1;
      pParse->nMem += nPk;
      for(i=0; i<nPk; i++){
        int k;
        assert( pPk->aiColumn[i]>=0 );
        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
        sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i);
        VdbeComment((v, "%s.%s", pIdx->zName,
                    pTab->aCol[pPk->aiColumn[i]].zName));
      }
      sqlite3VdbeVerifyAbortable(v, OE_Abort);
      i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk);
      VdbeCoverage(v);







|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
      int nPk = pPk->nKeyCol;
      int iPk = pParse->nMem+1;
      pParse->nMem += nPk;
      for(i=0; i<nPk; i++){
        int k;
        assert( pPk->aiColumn[i]>=0 );
        k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]);
        sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i);
        VdbeComment((v, "%s.%s", pIdx->zName,
                    pTab->aCol[pPk->aiColumn[i]].zName));
      }
      sqlite3VdbeVerifyAbortable(v, OE_Abort);
      i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk);
      VdbeCoverage(v);

Changes to src/vdbeapi.c.

1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
....
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
  /* Test that this call is being made from within an SQLITE_DELETE or
  ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
  if( !p || p->op==SQLITE_INSERT ){
    rc = SQLITE_MISUSE_BKPT;
    goto preupdate_old_out;
  }
  if( p->pPk ){
    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_old_out;
  }

  /* If the old.* record has not yet been loaded into memory, do so now. */
................................................................................
  Mem *pMem;

  if( !p || p->op==SQLITE_DELETE ){
    rc = SQLITE_MISUSE_BKPT;
    goto preupdate_new_out;
  }
  if( p->pPk && p->op!=SQLITE_UPDATE ){
    iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_new_out;
  }

  if( p->op==SQLITE_INSERT ){







|







 







|







1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
....
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
  /* Test that this call is being made from within an SQLITE_DELETE or
  ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
  if( !p || p->op==SQLITE_INSERT ){
    rc = SQLITE_MISUSE_BKPT;
    goto preupdate_old_out;
  }
  if( p->pPk ){
    iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_old_out;
  }

  /* If the old.* record has not yet been loaded into memory, do so now. */
................................................................................
  Mem *pMem;

  if( !p || p->op==SQLITE_DELETE ){
    rc = SQLITE_MISUSE_BKPT;
    goto preupdate_new_out;
  }
  if( p->pPk && p->op!=SQLITE_UPDATE ){
    iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_new_out;
  }

  if( p->op==SQLITE_INSERT ){

Changes to src/where.c.

5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
          int x = pOp->p2;
          assert( pIdx->pTable==pTab );
          if( !HasRowid(pTab) ){
            Index *pPk = sqlite3PrimaryKeyIndex(pTab);
            x = pPk->aiColumn[x];
            assert( x>=0 );
          }else{
            x = sqlite3ColumnOfStorage(pTab,x);
          }
          x = sqlite3ColumnOfIndex(pIdx, x);
          if( x>=0 ){
            pOp->p2 = x;
            pOp->p1 = pLevel->iIdxCur;
            OpcodeRewriteTrace(db, k, pOp);
          }
          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 
              || pWInfo->eOnePass );







|

|







5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
          int x = pOp->p2;
          assert( pIdx->pTable==pTab );
          if( !HasRowid(pTab) ){
            Index *pPk = sqlite3PrimaryKeyIndex(pTab);
            x = pPk->aiColumn[x];
            assert( x>=0 );
          }else{
            x = sqlite3StorageColumnToTable(pTab,x);
          }
          x = sqlite3TableColumnToIndex(pIdx, x);
          if( x>=0 ){
            pOp->p2 = x;
            pOp->p1 = pLevel->iIdxCur;
            OpcodeRewriteTrace(db, k, pOp);
          }
          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 
              || pWInfo->eOnePass );

Changes to src/wherecode.c.

819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
....
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
** accessed through the index.  If it cannot, then set pWalker->eCode to 1.
*/
static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
  struct CCurHint *pHint = pWalker->u.pCCurHint;
  assert( pHint->pIdx!=0 );
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pHint->iTabCur
   && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0
  ){
    pWalker->eCode = 1;
  }
  return WRC_Continue;
}

/*
................................................................................
    if( pExpr->iTable!=pHint->iTabCur ){
      int reg = ++pWalker->pParse->nMem;   /* Register for column value */
      sqlite3ExprCode(pWalker->pParse, pExpr, reg);
      pExpr->op = TK_REGISTER;
      pExpr->iTable = reg;
    }else if( pHint->pIdx!=0 ){
      pExpr->iTable = pHint->iIdxCur;
      pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn);
      assert( pExpr->iColumn>=0 );
    }
  }else if( pExpr->op==TK_AGG_FUNCTION ){
    /* An aggregate function in the WHERE clause of a query means this must
    ** be a correlated sub-query, and expression pExpr is an aggregate from
    ** the parent context. Do not walk the function arguments in this case.
    **
................................................................................
      }else{
        codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
      }
    }else if( iCur!=iIdxCur ){
      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
      iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
      for(j=0; j<pPk->nKeyCol; j++){
        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
      }
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
                           iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
    }

    /* If pIdx is an index on one or more expressions, then look through







|







 







|







 







|







819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
....
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
** accessed through the index.  If it cannot, then set pWalker->eCode to 1.
*/
static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
  struct CCurHint *pHint = pWalker->u.pCCurHint;
  assert( pHint->pIdx!=0 );
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pHint->iTabCur
   && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0
  ){
    pWalker->eCode = 1;
  }
  return WRC_Continue;
}

/*
................................................................................
    if( pExpr->iTable!=pHint->iTabCur ){
      int reg = ++pWalker->pParse->nMem;   /* Register for column value */
      sqlite3ExprCode(pWalker->pParse, pExpr, reg);
      pExpr->op = TK_REGISTER;
      pExpr->iTable = reg;
    }else if( pHint->pIdx!=0 ){
      pExpr->iTable = pHint->iIdxCur;
      pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn);
      assert( pExpr->iColumn>=0 );
    }
  }else if( pExpr->op==TK_AGG_FUNCTION ){
    /* An aggregate function in the WHERE clause of a query means this must
    ** be a correlated sub-query, and expression pExpr is an aggregate from
    ** the parent context. Do not walk the function arguments in this case.
    **
................................................................................
      }else{
        codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
      }
    }else if( iCur!=iIdxCur ){
      Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
      iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
      for(j=0; j<pPk->nKeyCol; j++){
        k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
      }
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
                           iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
    }

    /* If pIdx is an index on one or more expressions, then look through