SQLite4
Check-in [3841829752]
Not logged in

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

Overview
Comment:Changes to support "real" user-defined primary keys. This is quite broken at present.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | primary-keys
Files: files | file ages | folders
SHA1: 38418297529f4b0b360ae17814cfda663598e03f
User & Date: dan 2012-04-10 19:52:18
Context
2012-04-11
15:01
Fix various bugs. check-in: a70fb0629b user: dan tags: primary-keys
2012-04-10
19:52
Changes to support "real" user-defined primary keys. This is quite broken at present. check-in: 3841829752 user: dan tags: primary-keys
2012-03-01
14:47
Minor changes so that the code builds on Mac. check-in: a03018e6b8 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

211
212
213
214
215
216
217
218




219
220
221
222
223
224
225
226
227
228








229
230
231
232
233
234
235
...
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
...
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
....
1125
1126
1127
1128
1129
1130
1131

1132

1133
1134
1135
1136
1137
1138
1139
....
1150
1151
1152
1153
1154
1155
1156


1157
1158
1159

1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171



1172

1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183
....
1415
1416
1417
1418
1419
1420
1421



































































































1422
1423
1424
1425
1426
1427
1428
....
1445
1446
1447
1448
1449
1450
1451


1452
1453
1454
1455
1456
1457
1458
1459
1460
1461











1462
1463
1464
1465
1466
1467
1468
....
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
....
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
....
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
....
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
....
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
....
2335
2336
2337
2338
2339
2340
2341
2342

2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
....
2373
2374
2375
2376
2377
2378
2379

2380
2381
2382
2383
2384
2385
2386
....
2413
2414
2415
2416
2417
2418
2419




2420
2421
2422
2423
2424


2425
2426

2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
....
2445
2446
2447
2448
2449
2450
2451

2452
2453
2454
2455
2456
2457
2458
....
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477



2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501



2502
2503
2504
2505
2506
2507
2508
....
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
....
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
....
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
....
2711
2712
2713
2714
2715
2716
2717
2718


2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767

2768
2769
2770
2771
2772
2773
2774
....
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
....
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
....
3651
3652
3653
3654
3655
3656
3657

3658
3659
3660

3661
3662
3663









3664
3665
3666
3667

3668
3669
3670
3671
3672
3673









3674





3675
3676
3677
3678
3679
3680
3681
3682
  pParse->cookieMask = 0;
  pParse->cookieGoto = 0;
}

/*
** Find an available table number for database iDb
*/
static int firstAvailableTableNumber(sqlite4 *db, int iDb){




  HashElem *i;
  int maxTab = 1;
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); i;i=sqliteHashNext(i)){
    Table *pTab = (Table*)sqliteHashData(i);
    if( pTab->tnum > maxTab ) maxTab = pTab->tnum;
  }
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash); i;i=sqliteHashNext(i)){
    Index *pIdx = (Index*)sqliteHashData(i);
    if( pIdx->tnum > maxTab ) maxTab = pIdx->tnum;
  }








  return maxTab+1;
}

/*
** Run the parser and code generator recursively in order to generate
** code for the SQL statement given onto the end of the pParse context
** currently under construction.  When the parser is run recursively
................................................................................
  ** and allocate the record number for the table entry now.  Before any
  ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
  ** indices to be created and the table record must come before the 
  ** indices.  Hence, the record number for the table must be allocated
  ** now.
  */
  if( !db->init.busy && (v = sqlite4GetVdbe(pParse))!=0 ){
    int reg1, reg2, reg3;
    sqlite4BeginWriteOperation(pParse, 0, iDb);

#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( isVirtual ){
      sqlite4VdbeAddOp0(v, OP_VBegin);
    }
#endif
................................................................................
    **
    ** The rowid for the new entry is left in register pParse->regRowid.
    ** The root page number of the new table is left in reg pParse->regRoot.
    ** The rowid and root page number values are needed by the code that
    ** sqlite4EndTable will generate.
    */
    reg1 = pParse->regRowid = ++pParse->nMem;
    reg2 = pParse->regRoot = ++pParse->nMem;
    reg3 = ++pParse->nMem;

#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
    if( isView || isVirtual ){
      sqlite4VdbeAddOp2(v, OP_Integer, 0, reg2);
    }else
#endif
    {
      int tnum = firstAvailableTableNumber(db, iDb);
      sqlite4VdbeAddOp2(v, OP_Integer, tnum, reg2);
    }

    sqlite4OpenMasterTable(pParse, iDb);
    sqlite4VdbeAddOp2(v, OP_NewRowid, 0, reg1);
    sqlite4VdbeAddOp2(v, OP_Null, 0, reg3);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
    sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
    sqlite4VdbeAddOp0(v, OP_Close);
  }
................................................................................
  Parse *pParse,    /* Parsing context */
  ExprList *pList,  /* List of field names to be indexed */
  int onError,      /* What to do with a uniqueness conflict */
  int autoInc,      /* True if the AUTOINCREMENT keyword is present */
  int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
){
  Table *pTab = pParse->pNewTable;

  char *zType = 0;

  int iCol = -1, i;
  if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
  if( pTab->tabFlags & TF_HasPrimaryKey ){
    sqlite4ErrorMsg(pParse, 
      "table \"%s\" has more than one primary key", pTab->zName);
    goto primary_key_exit;
  }
................................................................................
      }
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }


  if( iCol>=0 && iCol<pTab->nCol ){
    zType = pTab->aCol[iCol].zType;
  }

  if( zType && sqlite4StrICmp(zType, "INTEGER")==0
        && sortOrder==SQLITE_SO_ASC ){
    pTab->iPKey = iCol;
    pTab->keyConf = (u8)onError;
    assert( autoInc==0 || autoInc==1 );
    pTab->tabFlags |= autoInc*TF_Autoincrement;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite4ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{



    Index *p;

    p = sqlite4CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
    if( p ){
      p->autoIndex = 2;
    }

    pList = 0;
  }

primary_key_exit:
  sqlite4ExprListDelete(pParse->db, pList);
  return;
}
................................................................................
    memcpy(&zStmt[k], zType, len);
    k += len;
    assert( k<=n );
  }
  sqlite4_snprintf(n-k, &zStmt[k], "%s", zEnd);
  return zStmt;
}




































































































/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
................................................................................
  Token *pCons,           /* The ',' token after the last column defn. */
  Token *pEnd,            /* The final ')' token in the CREATE TABLE */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;
  sqlite4 *db = pParse->db;
  int iDb;



  if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );

  iDb = sqlite4SchemaToIndex(db, p->pSchema);












#ifndef SQLITE_OMIT_CHECK
  /* Resolve names in all CHECK constraint expressions.
  */
  if( p->pCheck ){
    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
    NameContext sNC;                /* Name context for pParse->pNewTable */
................................................................................
    sNC.isCheck = 1;
    if( sqlite4ResolveExprNames(&sNC, p->pCheck) ){
      return;
    }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  */
  if( db->init.busy ){
    p->tnum = db->init.newTnum;
  }

  /* If not initializing, then create a record for the new table
  ** in the SQLITE_MASTER table of the database.
  **
  ** If this is a TEMPORARY table, write the entry into the auxiliary
  ** file instead of into the main database file.
  */
  if( !db->init.busy ){
................................................................................
    ** be redundant.
    */
    if( pSelect ){
      SelectDest dest;
      Table *pSelTab;

      assert(pParse->nTab==1);
      sqlite4VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
      sqlite4VdbeChangeP5(v, 1);
      pParse->nTab = 2;
      sqlite4SelectDestInit(&dest, SRT_Table, 1);
      sqlite4Select(pParse, pSelect, &dest);
      sqlite4VdbeAddOp1(v, OP_Close, 1);
      if( pParse->nErr==0 ){
        pSelTab = sqlite4ResultSetOfSelect(pParse, pSelect);
        if( pSelTab==0 ) return;
................................................................................

    /* A slot for the record has already been allocated in the 
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.
    */
    sqlite4NestedParse(pParse,
      "UPDATE %Q.%s "
         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
       "WHERE rowid=#%d",
      db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
      zType,
      p->zName,
      p->zName,
      pParse->regRoot,
      zStmt,
      pParse->regRowid
    );
    sqlite4DbFree(db, zStmt);
    sqlite4ChangeCookie(pParse, iDb);

#ifndef SQLITE_OMIT_AUTOINCREMENT
................................................................................
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
  Index *pIdx;
  int iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
  destroyRootPage(pParse, pTab->tnum, iDb);
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    destroyRootPage(pParse, pIdx->tnum, iDb);
  }
}

/*
** Remove entries from the sqlite_statN tables (for N in (1,2,3))
................................................................................
  sqlite4VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
#else
  iSorter = iTab;
#endif

  /* Open the table. Loop through all rows of the table, inserting index
  ** records into the sorter. */
  sqlite4OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);
  regRecord = sqlite4GetTempRange(pParse,2);

#ifndef SQLITE_OMIT_MERGE_SORT
  sqlite4GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, iIdx);
  sqlite4VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  sqlite4VdbeAddOp2(v, OP_Next, iTab, addr1+1);
................................................................................
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins this statement */
  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
  int sortOrder,     /* Sort order of primary key when pList==NULL */
  int ifNotExist     /* Omit error if index already exists */

){
  Index *pRet = 0;     /* Pointer to return */
  Table *pTab = 0;     /* Table to be indexed */
  Index *pIndex = 0;   /* The index to be created */
  char *zName = 0;     /* Name of the index */
  int nName;           /* Number of characters in zName */
  int i, j;
  Token nullId;        /* Fake token for an empty ID list */
  DbFixer sFix;        /* For assigning database names to pTable */
  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
  sqlite4 *db = pParse->db;
  Db *pDb;             /* The specific table containing the indexed database */
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */
  int nCol;
  int nExtra = 0;
  char *zExtra;

  assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
  assert( pParse->nErr==0 );      /* Never called with prior errors */
  if( db->mallocFailed || IN_DECLARE_VTAB ){
    goto exit_create_index;
................................................................................
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
    ** to search for the table. 'Fix' the table name to this db
    ** before looking up the table.
    */

    assert( pName1 && pName2 );
    iDb = sqlite4TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ) goto exit_create_index;
    assert( pName && pName->z );

#ifndef SQLITE_OMIT_TEMPDB
    /* If the index name was unqualified, check if the the table
................................................................................
    if( !pTab ) goto exit_create_index;
    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  }
  pDb = &db->aDb[iDb];

  assert( pTab!=0 );
  assert( pParse->nErr==0 );




  if( sqlite4StrNICmp(pTab->zName, "sqlite_", 7)==0 
       && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
    sqlite4ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }


#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){

    sqlite4ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){

    sqlite4ErrorMsg(pParse, "virtual tables may not be indexed");
    goto exit_create_index;
  }
#endif

  /*
  ** Find the name of the index.  Make sure there is not already another
................................................................................
  ** index, then we will continue to process this index.
  **
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.
  */
  if( pName ){

    zName = sqlite4NameFromToken(db, pName);
    if( zName==0 ) goto exit_create_index;
    assert( pName->z!=0 );
    if( SQLITE_OK!=sqlite4CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){
................................................................................
        sqlite4ErrorMsg(pParse, "index %s already exists", zName);
      }else{
        assert( !db->init.busy );
        sqlite4CodeVerifySchema(pParse, iDb);
      }
      goto exit_create_index;
    }
  }else{
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    zName = sqlite4MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n);



    if( zName==0 ){
      goto exit_create_index;
    }
  }

  /* Check for authorization to create an index.
  */
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    const char *zDb = pDb->zName;
    if( sqlite4AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
      goto exit_create_index;
    }
    i = SQLITE_CREATE_INDEX;
    if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
    if( sqlite4AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
      goto exit_create_index;
    }
  }
#endif

  /* If pList==0, it means this routine was called to make a primary
  ** key out of the last column added to the table under construction.
  ** So create a fake list to simulate this.



  */
  if( pList==0 ){
    nullId.z = pTab->aCol[pTab->nCol-1].zName;
    nullId.n = sqlite4Strlen30((char*)nullId.z);
    pList = sqlite4ExprListAppend(pParse, 0, 0);
    if( pList==0 ) goto exit_create_index;
    sqlite4ExprListSetName(pParse, pList, &nullId, 0);
................................................................................
      ** failure we have quit before reaching this point. */
      if( ALWAYS(pColl) ){
        nExtra += (1 + sqlite4Strlen30(pColl->zName));
      }
    }
  }

  /* 
  ** Allocate the index structure. 
  */
  nName = sqlite4Strlen30(zName);
  nCol = pList->nExpr;
  pIndex = sqlite4DbMallocZero(db, 
      ROUND8(sizeof(Index)) +              /* Index structure  */
      ROUND8(sizeof(tRowcnt)*(nCol+1)) +   /* Index.aiRowEst   */
      sizeof(char *)*nCol +                /* Index.azColl     */
      sizeof(int)*nCol +                   /* Index.aiColumn   */
      sizeof(u8)*nCol +                    /* Index.aSortOrder */
      nName + 1 +                          /* Index.zName      */
      nExtra                               /* Collation sequence names */
  );
  if( db->mallocFailed ){
    goto exit_create_index;
  }
  zExtra = (char*)pIndex;
  pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
  pIndex->azColl = (char**)
     ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
  assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
  assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
  pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
  pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
  pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
  zExtra = (char *)(&pIndex->zName[nName+1]);
  memcpy(pIndex->zName, zName, nName+1);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
  pIndex->onError = (u8)onError;
  pIndex->autoIndex = (u8)(pName==0);
  pIndex->pSchema = db->aDb[iDb].pSchema;

  /* Check to see if we should honor DESC requests on index columns
  */
  if( pDb->pSchema->file_format>=4 ){
    sortOrderMask = -1;   /* Honor DESC */
  }else{
    sortOrderMask = 0;    /* Ignore DESC */
................................................................................
    ** the constraint occur in different orders, then the constraints are
    ** considered distinct and both result in separate indices.
    */
    Index *pIdx;
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int k;
      assert( pIdx->onError!=OE_None );
      assert( pIdx->autoIndex );
      assert( pIndex->onError!=OE_None );

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){
        const char *z1;
        const char *z2;
        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
................................................................................
    }
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 
  */
  if( db->init.busy ){
    Index *p;
    p = sqlite4HashInsert(&pIndex->pSchema->idxHash, 
                          pIndex->zName, sqlite4Strlen30(pIndex->zName),
                          pIndex);
    if( p ){
      assert( p==pIndex );  /* Malloc must have failed */
      db->mallocFailed = 1;
      goto exit_create_index;
    }
    db->flags |= SQLITE_InternChanges;
    if( pTblName!=0 ){
      pIndex->tnum = db->init.newTnum;
    }
  }

  /* If the db->init.busy is 0 then create the index on disk.  This
  ** involves writing the index into the master table and filling in the
  ** index with the current table contents.
................................................................................
  ** we don't want to recreate it.
  **
  ** If pTblName==0 it means this index is generated as a primary key
  ** or UNIQUE constraint of a CREATE TABLE statement.  Since the table
  ** has just been created, it contains no data and the index initialization
  ** step can be skipped.
  */
  else{ /* if( db->init.busy==0 ) */


    Vdbe *v;
    char *zStmt;

    v = sqlite4GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;


    /* Create the rootpage for the index
    */
    sqlite4BeginWriteOperation(pParse, 1, iDb);
    pIndex->tnum = firstAvailableTableNumber(db, iDb);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart ){
      assert( pEnd!=0 );
      /* A named index with an explicit CREATE INDEX statement */
      zStmt = sqlite4MPrintf(db, "CREATE%s INDEX %.*s",
        onError==OE_None ? "" : " UNIQUE",
        (int)(pEnd->z - pName->z) + 1,
        pName->z);
    }else{
      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
      /* zStmt = sqlite4MPrintf(""); */
      zStmt = 0;
    }

    /* Add an entry in sqlite_master for this index
    */
    sqlite4NestedParse(pParse, 
        "INSERT INTO %Q.%s VALUES('index',%Q,%Q,%d,%Q);",
        db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
        pIndex->zName,
        pTab->zName,
        pIndex->tnum,
        zStmt
    );
    sqlite4DbFree(db, zStmt);

    /* Fill the index with data and reparse the schema. Code an OP_Expire
    ** to invalidate all pre-compiled statements.
    */
    if( pTblName ){
      sqlite4RefillIndex(pParse, pIndex);
      sqlite4ChangeCookie(pParse, iDb);
      sqlite4VdbeAddParseSchemaOp(v, iDb,
         sqlite4MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
      sqlite4VdbeAddOp1(v, OP_Expire, 0);

    }
  }

  /* When adding an index to the list of indices for a table, make
  ** sure all indices labeled OE_Replace come after all those labeled
  ** OE_Ignore.  This is necessary for the correct constraint check
  ** processing (in sqlite4GenerateConstraintChecks()) as part of
................................................................................
**
** aiRowEst[0] is suppose to contain the number of elements in the index.
** Since we do not know, guess 1 million.  aiRowEst[1] is an estimate of the
** number of rows in the table that match any particular value of the
** first column of the index.  aiRowEst[2] is an estimate of the number
** of rows that match any particular combiniation of the first 2 columns
** of the index.  And so forth.  It must always be the case that
*
**           aiRowEst[N]<=aiRowEst[N-1]
**           aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized.  The numbers generated here
** are based on typical values found in actual indices.
*/
................................................................................
      sqlite4ErrorMsg(pParse, "no such index: %S", pName, 0);
    }else{
      sqlite4CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
    }
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqlite4ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
    goto exit_drop_index;
  }
  iDb = sqlite4SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
................................................................................
** If successful, a pointer to the new structure is returned. In this case
** the caller is responsible for calling sqlite4DbFree(db, ) on the returned 
** pointer. If an error occurs (out of memory or missing collation 
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
*/
KeyInfo *sqlite4IndexKeyinfo(Parse *pParse, Index *pIdx){

  int i;
  int nCol = pIdx->nColumn;
  int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;

  sqlite4 *db = pParse->db;
  KeyInfo *pKey = (KeyInfo *)sqlite4DbMallocZero(db, nBytes);










  if( pKey ){
    pKey->db = pParse->db;
    pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
    assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );

    for(i=0; i<nCol; i++){
      char *zColl = pIdx->azColl[i];
      assert( zColl );
      pKey->aColl[i] = sqlite4LocateCollSeq(pParse, zColl);
      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
    }









    pKey->nField = (u16)nCol;





  }

  if( pParse->nErr ){
    sqlite4DbFree(db, pKey);
    pKey = 0;
  }
  return pKey;
}







|
>
>
>
>


<
<
<
|




>
>
>
>
>
>
>
>







 







|







 







<

>









>







 







>

>







 







>
>



>











|
>
>
>

>
|
<
<
<
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>








<

>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<







 







|
<







 







|





|







 







<







 







|







 







|
>





<









<







 







>







 







>
>
>
>





>
>


>






>







 







>







 







|




>
>
>
|
|
<





|












|
|
|
>
>
>







 







|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







<
<
<
<
<
<
<
<
<

|







 







|
>
>
|
|

|
|

<
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
>







 







|







 







|







 







>

|
<
>

|

>
>
>
>
>
>
>
>
>




>
|





>
>
>
>
>
>
>
>
>

>
>
>
>
>








211
212
213
214
215
216
217
218
219
220
221
222
223
224



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
...
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
....
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
....
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192



1193
1194
1195
1196
1197
1198
1199
1200
....
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
....
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
....
1606
1607
1608
1609
1610
1611
1612










1613
1614
1615
1616
1617
1618
1619
....
1657
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
....
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
....
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
....
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
....
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464

2465
2466
2467
2468
2469
2470
2471
2472
2473

2474
2475
2476
2477
2478
2479
2480
....
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
....
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
....
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
....
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607

2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
....
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668





















2669
2670
2671
2672
2673
2674
2675
....
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
....
2790
2791
2792
2793
2794
2795
2796









2797
2798
2799
2800
2801
2802
2803
2804
2805
....
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826

2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
....
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
....
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
....
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762

3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
  pParse->cookieMask = 0;
  pParse->cookieGoto = 0;
}

/*
** Find an available table number for database iDb
*/
static int firstAvailableTableNumber(
  sqlite4 *db,                    /* Database handle */
  int iDb,                        /* Index of database in db->aDb[] */
  Table *pTab                     /* New table being constructed */
){
  HashElem *i;
  int maxTab = 1;




  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash); i;i=sqliteHashNext(i)){
    Index *pIdx = (Index*)sqliteHashData(i);
    if( pIdx->tnum > maxTab ) maxTab = pIdx->tnum;
  }

  if( pTab ){
    Index *pIdx;
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      if( pIdx->tnum > maxTab ) maxTab = pIdx->tnum;
    }
  }

  return maxTab+1;
}

/*
** Run the parser and code generator recursively in order to generate
** code for the SQL statement given onto the end of the pParse context
** currently under construction.  When the parser is run recursively
................................................................................
  ** and allocate the record number for the table entry now.  Before any
  ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
  ** indices to be created and the table record must come before the 
  ** indices.  Hence, the record number for the table must be allocated
  ** now.
  */
  if( !db->init.busy && (v = sqlite4GetVdbe(pParse))!=0 ){
    int reg1, reg3;
    sqlite4BeginWriteOperation(pParse, 0, iDb);

#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( isVirtual ){
      sqlite4VdbeAddOp0(v, OP_VBegin);
    }
#endif
................................................................................
    **
    ** The rowid for the new entry is left in register pParse->regRowid.
    ** The root page number of the new table is left in reg pParse->regRoot.
    ** The rowid and root page number values are needed by the code that
    ** sqlite4EndTable will generate.
    */
    reg1 = pParse->regRowid = ++pParse->nMem;

    reg3 = ++pParse->nMem;
#if 0
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
    if( isView || isVirtual ){
      sqlite4VdbeAddOp2(v, OP_Integer, 0, reg2);
    }else
#endif
    {
      int tnum = firstAvailableTableNumber(db, iDb);
      sqlite4VdbeAddOp2(v, OP_Integer, tnum, reg2);
    }
#endif
    sqlite4OpenMasterTable(pParse, iDb);
    sqlite4VdbeAddOp2(v, OP_NewRowid, 0, reg1);
    sqlite4VdbeAddOp2(v, OP_Null, 0, reg3);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
    sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
    sqlite4VdbeAddOp0(v, OP_Close);
  }
................................................................................
  Parse *pParse,    /* Parsing context */
  ExprList *pList,  /* List of field names to be indexed */
  int onError,      /* What to do with a uniqueness conflict */
  int autoInc,      /* True if the AUTOINCREMENT keyword is present */
  int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
){
  Table *pTab = pParse->pNewTable;
#if 0
  char *zType = 0;
#endif
  int iCol = -1, i;
  if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
  if( pTab->tabFlags & TF_HasPrimaryKey ){
    sqlite4ErrorMsg(pParse, 
      "table \"%s\" has more than one primary key", pTab->zName);
    goto primary_key_exit;
  }
................................................................................
      }
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }

#if 0
  if( iCol>=0 && iCol<pTab->nCol ){
    zType = pTab->aCol[iCol].zType;
  }

  if( zType && sqlite4StrICmp(zType, "INTEGER")==0
        && sortOrder==SQLITE_SO_ASC ){
    pTab->iPKey = iCol;
    pTab->keyConf = (u8)onError;
    assert( autoInc==0 || autoInc==1 );
    pTab->tabFlags |= autoInc*TF_Autoincrement;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite4ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else
#endif

  {
    Index *p;
    p = sqlite4CreateIndex(
        pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, 1



    );
    pList = 0;
  }

primary_key_exit:
  sqlite4ExprListDelete(pParse->db, pList);
  return;
}
................................................................................
    memcpy(&zStmt[k], zType, len);
    k += len;
    assert( k<=n );
  }
  sqlite4_snprintf(n-k, &zStmt[k], "%s", zEnd);
  return zStmt;
}

static Index *newIndex(
  Parse *pParse,                  /* Parse context for current statement */
  Table *pTab,                    /* Table index is created on */
  const char *zName,              /* Name of index object to create */
  int nCol,                       /* Number of columns in index */
  int onError,                    /* One of OE_Abort, OE_Replace etc. */
  int nExtra,                     /* Bytes of extra space to allocate */
  char **pzExtra                  /* OUT: Pointer to extra space */
){
  sqlite4 *db = pParse->db;       /* Database handle */
  Index *pIndex;                  /* Return value */
  char *zExtra = 0;               /* nExtra bytes of extra space allocated */
  int nName;                      /* Length of zName in bytes */

  /* Allocate the index structure. */
  nName = sqlite4Strlen30(zName);
  pIndex = sqlite4DbMallocZero(db, 
      ROUND8(sizeof(Index)) +              /* Index structure  */
      ROUND8(sizeof(tRowcnt)*(nCol+1)) +   /* Index.aiRowEst   */
      sizeof(char *)*nCol +                /* Index.azColl     */
      sizeof(int)*nCol +                   /* Index.aiColumn   */
      sizeof(u8)*nCol +                    /* Index.aSortOrder */
      nName + 1 +                          /* Index.zName      */
      nExtra                               /* Collation sequence names */
  );
  assert( pIndex || db->mallocFailed );

  if( pIndex ){
    zExtra = (char*)pIndex;
    pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
    pIndex->azColl = (char**)
      ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
    assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
    assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
    pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
    pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
    pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
    zExtra = (char *)(&pIndex->zName[nName+1]);
    memcpy(pIndex->zName, zName, nName+1);
    pIndex->pTable = pTab;
    pIndex->nColumn = nCol;
    pIndex->onError = (u8)onError;
    pIndex->pSchema = pTab->pSchema;

    if( db->init.busy ){
      Hash *pIdxHash = &pIndex->pSchema->idxHash;
      Index *p;

      p = sqlite4HashInsert(pIdxHash, pIndex->zName, nName, pIndex);
      if( p ){
        assert( p==pIndex );
        db->mallocFailed = 1;
        sqlite4DbFree(db, pIndex);
        pIndex = 0;
      }
    }
  }

  *pzExtra = zExtra;
  return pIndex;
}


/*
** Allocate and populate an Index structure representing an implicit 
** primary key. In implicit primary key behaves similarly to the built-in
** INTEGER PRIMARY KEY columns in SQLite 3.
*/
static void addImplicitPrimaryKey(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table to add implicit PRIMARY KEY to */
  int iDb
){
  Index *pIndex;                  /* New index */
  char *zExtra;

  assert( !pTab->pIndex || pTab->pIndex->eIndexType!=SQLITE_INDEX_PRIMARYKEY );
  assert( sqlite4Strlen30("binary")==6 );
  pIndex = newIndex(pParse, pTab, pTab->zName, 1, OE_Abort, 1+6, &zExtra);
  if( pIndex ){
    sqlite4 *db = pParse->db;

    pIndex->aiColumn[0] = -1;
    pIndex->azColl[0] = zExtra;
    memcpy(zExtra, "binary", 7);
    pIndex->eIndexType = SQLITE_INDEX_PRIMARYKEY;
    pIndex->pNext = pTab->pIndex;
    pTab->pIndex = pIndex;
    sqlite4DefaultRowEst(pIndex);
    pTab->tabFlags |= TF_HasPrimaryKey;

    if( db->init.busy ){
      pIndex->tnum = db->init.newTnum;
    }else{
      pIndex->tnum = firstAvailableTableNumber(db, iDb, pTab);
    }
  }
}

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
................................................................................
  Token *pCons,           /* The ',' token after the last column defn. */
  Token *pEnd,            /* The final ')' token in the CREATE TABLE */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;
  sqlite4 *db = pParse->db;
  int iDb;
  int iPkRoot = 0;                /* Root page of primary key index */
  Index *pPk;                     /* PRIMARY KEY index for table p */

  if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );

  iDb = sqlite4SchemaToIndex(db, p->pSchema);

  if( 0==(p->tabFlags & TF_HasPrimaryKey) ){
    /* If no explicit PRIMARY KEY has been created, add an implicit 
    ** primary key here.  An implicit primary key works the way "rowid" did
    ** in SQLite 3.  */
    addImplicitPrimaryKey(pParse, p, iDb);
  }
  pPk = sqlite4FindPrimaryKey(p, 0);
  assert( pPk || pParse->nErr || db->mallocFailed );
  if( pPk ) iPkRoot = pPk->tnum;


#ifndef SQLITE_OMIT_CHECK
  /* Resolve names in all CHECK constraint expressions.
  */
  if( p->pCheck ){
    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
    NameContext sNC;                /* Name context for pParse->pNewTable */
................................................................................
    sNC.isCheck = 1;
    if( sqlite4ResolveExprNames(&sNC, p->pCheck) ){
      return;
    }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */











  /* If not initializing, then create a record for the new table
  ** in the SQLITE_MASTER table of the database.
  **
  ** If this is a TEMPORARY table, write the entry into the auxiliary
  ** file instead of into the main database file.
  */
  if( !db->init.busy ){
................................................................................
    ** be redundant.
    */
    if( pSelect ){
      SelectDest dest;
      Table *pSelTab;

      assert(pParse->nTab==1);
      sqlite4VdbeAddOp3(v, OP_OpenWrite, 1, iPkRoot, iDb);

      pParse->nTab = 2;
      sqlite4SelectDestInit(&dest, SRT_Table, 1);
      sqlite4Select(pParse, pSelect, &dest);
      sqlite4VdbeAddOp1(v, OP_Close, 1);
      if( pParse->nErr==0 ){
        pSelTab = sqlite4ResultSetOfSelect(pParse, pSelect);
        if( pSelTab==0 ) return;
................................................................................

    /* A slot for the record has already been allocated in the 
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.
    */
    sqlite4NestedParse(pParse,
      "UPDATE %Q.%s "
         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=%d, sql=%Q "
       "WHERE rowid=#%d",
      db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
      zType,
      p->zName,
      p->zName,
      iPkRoot,
      zStmt,
      pParse->regRowid
    );
    sqlite4DbFree(db, zStmt);
    sqlite4ChangeCookie(pParse, iDb);

#ifndef SQLITE_OMIT_AUTOINCREMENT
................................................................................
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
  Index *pIdx;
  int iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);

  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    destroyRootPage(pParse, pIdx->tnum, iDb);
  }
}

/*
** Remove entries from the sqlite_statN tables (for N in (1,2,3))
................................................................................
  sqlite4VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
#else
  iSorter = iTab;
#endif

  /* Open the table. Loop through all rows of the table, inserting index
  ** records into the sorter. */
  sqlite4OpenPrimaryKey(pParse, iTab, iDb, pTab, OP_OpenRead);
  addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);
  regRecord = sqlite4GetTempRange(pParse,2);

#ifndef SQLITE_OMIT_MERGE_SORT
  sqlite4GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, iIdx);
  sqlite4VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  sqlite4VdbeAddOp2(v, OP_Next, iTab, addr1+1);
................................................................................
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins this statement */
  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
  int sortOrder,     /* Sort order of primary key when pList==NULL */
  int ifNotExist,    /* Omit error if index already exists */
  int bPrimaryKey    /* True to create the tables primary key */
){
  Index *pRet = 0;     /* Pointer to return */
  Table *pTab = 0;     /* Table to be indexed */
  Index *pIndex = 0;   /* The index to be created */
  char *zName = 0;     /* Name of the index */

  int i, j;
  Token nullId;        /* Fake token for an empty ID list */
  DbFixer sFix;        /* For assigning database names to pTable */
  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
  sqlite4 *db = pParse->db;
  Db *pDb;             /* The specific table containing the indexed database */
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */

  int nExtra = 0;
  char *zExtra;

  assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
  assert( pParse->nErr==0 );      /* Never called with prior errors */
  if( db->mallocFailed || IN_DECLARE_VTAB ){
    goto exit_create_index;
................................................................................
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
    ** to search for the table. 'Fix' the table name to this db
    ** before looking up the table.
    */
    assert( !bPrimaryKey );
    assert( pName1 && pName2 );
    iDb = sqlite4TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ) goto exit_create_index;
    assert( pName && pName->z );

#ifndef SQLITE_OMIT_TEMPDB
    /* If the index name was unqualified, check if the the table
................................................................................
    if( !pTab ) goto exit_create_index;
    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  }
  pDb = &db->aDb[iDb];

  assert( pTab!=0 );
  assert( pParse->nErr==0 );

  /* TODO: We will need to reinstate this block when sqlite_master is 
  ** modified to use an implicit primary key.  */
#if 0
  if( sqlite4StrNICmp(pTab->zName, "sqlite_", 7)==0 
       && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
    sqlite4ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#endif

#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    assert( !bPrimaryKey );
    sqlite4ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){
    assert( !bPrimaryKey );
    sqlite4ErrorMsg(pParse, "virtual tables may not be indexed");
    goto exit_create_index;
  }
#endif

  /*
  ** Find the name of the index.  Make sure there is not already another
................................................................................
  ** index, then we will continue to process this index.
  **
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.
  */
  if( pName ){
    assert( !bPrimaryKey );
    zName = sqlite4NameFromToken(db, pName);
    if( zName==0 ) goto exit_create_index;
    assert( pName->z!=0 );
    if( SQLITE_OK!=sqlite4CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){
................................................................................
        sqlite4ErrorMsg(pParse, "index %s already exists", zName);
      }else{
        assert( !db->init.busy );
        sqlite4CodeVerifySchema(pParse, iDb);
      }
      goto exit_create_index;
    }
  }else if( !bPrimaryKey ){
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    zName = sqlite4MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n);
  }else{
    zName = sqlite4MPrintf(db, "%s", pTab->zName);
  }
  if( zName==0 ){
    goto exit_create_index;

  }

  /* Check for authorization to create an index.
  */
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( bPrimaryKey==0 ){
    const char *zDb = pDb->zName;
    if( sqlite4AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
      goto exit_create_index;
    }
    i = SQLITE_CREATE_INDEX;
    if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
    if( sqlite4AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
      goto exit_create_index;
    }
  }
#endif

  /* If pList==0, it means this routine was called as a result of a PRIMARY
  ** KEY or UNIQUE constraint attached to the last column added to the table 
  ** under construction. So create a fake list to simulate this.
  **
  ** TODO: This 'fake list' could be created by the caller to reduce the
  ** number of parameters passed to this function.
  */
  if( pList==0 ){
    nullId.z = pTab->aCol[pTab->nCol-1].zName;
    nullId.n = sqlite4Strlen30((char*)nullId.z);
    pList = sqlite4ExprListAppend(pParse, 0, 0);
    if( pList==0 ) goto exit_create_index;
    sqlite4ExprListSetName(pParse, pList, &nullId, 0);
................................................................................
      ** failure we have quit before reaching this point. */
      if( ALWAYS(pColl) ){
        nExtra += (1 + sqlite4Strlen30(pColl->zName));
      }
    }
  }

  /* Allocate the new Index structure. */
  pIndex = newIndex(pParse, pTab, zName, pList->nExpr, onError, nExtra,&zExtra);
  if( !pIndex ) goto exit_create_index;

  assert( pIndex->eIndexType==SQLITE_INDEX_USER );
  if( pName==0 ){
    if( bPrimaryKey ){
      pIndex->eIndexType = SQLITE_INDEX_PRIMARYKEY;
    }else{
      pIndex->eIndexType = SQLITE_INDEX_UNIQUE;
    }
  }






















  /* Check to see if we should honor DESC requests on index columns
  */
  if( pDb->pSchema->file_format>=4 ){
    sortOrderMask = -1;   /* Honor DESC */
  }else{
    sortOrderMask = 0;    /* Ignore DESC */
................................................................................
    ** the constraint occur in different orders, then the constraints are
    ** considered distinct and both result in separate indices.
    */
    Index *pIdx;
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int k;
      assert( pIdx->onError!=OE_None );
      assert( pIdx->eIndexType!=SQLITE_INDEX_USER );
      assert( pIndex->onError!=OE_None );

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){
        const char *z1;
        const char *z2;
        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
................................................................................
    }
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 
  */
  if( db->init.busy ){









    db->flags |= SQLITE_InternChanges;
    if( pTblName!=0 || bPrimaryKey ){
      pIndex->tnum = db->init.newTnum;
    }
  }

  /* If the db->init.busy is 0 then create the index on disk.  This
  ** involves writing the index into the master table and filling in the
  ** index with the current table contents.
................................................................................
  ** we don't want to recreate it.
  **
  ** If pTblName==0 it means this index is generated as a primary key
  ** or UNIQUE constraint of a CREATE TABLE statement.  Since the table
  ** has just been created, it contains no data and the index initialization
  ** step can be skipped.
  */
  else{
    pIndex->tnum = firstAvailableTableNumber(db, iDb, pTab);
    if( bPrimaryKey==0 ){
      Vdbe *v;
      char *zStmt;

      v = sqlite4GetVdbe(pParse);
      if( v==0 ) goto exit_create_index;


      /* Create the rootpage for the index
      */
      sqlite4BeginWriteOperation(pParse, 1, iDb);
      pIndex->tnum = firstAvailableTableNumber(db, iDb, pTab);

      /* Gather the complete text of the CREATE INDEX statement into
       ** the zStmt variable
       */
      if( pStart ){
        assert( pEnd!=0 );
        /* A named index with an explicit CREATE INDEX statement */
        zStmt = sqlite4MPrintf(db, "CREATE%s INDEX %.*s",
            onError==OE_None ? "" : " UNIQUE",
            (int)(pEnd->z - pName->z) + 1,
            pName->z);
      }else{
        /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
        /* zStmt = sqlite4MPrintf(""); */
        zStmt = 0;
      }

      /* Add an entry in sqlite_master for this index
      */
      sqlite4NestedParse(pParse, 
          "INSERT INTO %Q.%s VALUES('index',%Q,%Q,%d,%Q);",
          db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
          pIndex->zName,
          pTab->zName,
          pIndex->tnum,
          zStmt
          );
      sqlite4DbFree(db, zStmt);

      /* Fill the index with data and reparse the schema. Code an OP_Expire
       ** to invalidate all pre-compiled statements.
       */
      if( pTblName ){
        sqlite4RefillIndex(pParse, pIndex);
        sqlite4ChangeCookie(pParse, iDb);
        sqlite4VdbeAddParseSchemaOp(v, iDb,
            sqlite4MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
        sqlite4VdbeAddOp1(v, OP_Expire, 0);
      }
    }
  }

  /* When adding an index to the list of indices for a table, make
  ** sure all indices labeled OE_Replace come after all those labeled
  ** OE_Ignore.  This is necessary for the correct constraint check
  ** processing (in sqlite4GenerateConstraintChecks()) as part of
................................................................................
**
** aiRowEst[0] is suppose to contain the number of elements in the index.
** Since we do not know, guess 1 million.  aiRowEst[1] is an estimate of the
** number of rows in the table that match any particular value of the
** first column of the index.  aiRowEst[2] is an estimate of the number
** of rows that match any particular combiniation of the first 2 columns
** of the index.  And so forth.  It must always be the case that
**
**           aiRowEst[N]<=aiRowEst[N-1]
**           aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized.  The numbers generated here
** are based on typical values found in actual indices.
*/
................................................................................
      sqlite4ErrorMsg(pParse, "no such index: %S", pName, 0);
    }else{
      sqlite4CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
    }
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->eIndexType!=SQLITE_INDEX_USER ){
    sqlite4ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
    goto exit_drop_index;
  }
  iDb = sqlite4SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
................................................................................
** If successful, a pointer to the new structure is returned. In this case
** the caller is responsible for calling sqlite4DbFree(db, ) on the returned 
** pointer. If an error occurs (out of memory or missing collation 
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
*/
KeyInfo *sqlite4IndexKeyinfo(Parse *pParse, Index *pIdx){
  Index *pPk;                     /* Primary key index on same table */
  int i;
  int nCol;

  int nBytes;
  sqlite4 *db = pParse->db;
  KeyInfo *pKey;

  if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
    pPk = 0;
  }else{
    pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
  }
  nCol = pIdx->nColumn + (pPk ? pPk->nColumn : 0);

  nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
  pKey = (KeyInfo *)sqlite4DbMallocZero(db, nBytes);
  if( pKey ){
    pKey->db = pParse->db;
    pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
    assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );

    for(i=0; i<pIdx->nColumn; i++){
      char *zColl = pIdx->azColl[i];
      assert( zColl );
      pKey->aColl[i] = sqlite4LocateCollSeq(pParse, zColl);
      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
    }
    if( pPk ){
      for(i=0; i<pPk->nColumn; i++){
        char *zColl = pIdx->azColl[i];
        assert( zColl );
        pKey->aColl[i+pIdx->nColumn] = sqlite4LocateCollSeq(pParse, zColl);
        pKey->aSortOrder[i+pIdx->nColumn] = pPk->aSortOrder[i];
      }
    }

    pKey->nField = (u16)nCol;
    if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
      pKey->nData = pIdx->pTable->nCol;
    }else{
      pKey->nPK = pPk->nColumn;
    }
  }

  if( pParse->nErr ){
    sqlite4DbFree(db, pKey);
    pKey = 0;
  }
  return pKey;
}

Changes to src/delete.c.

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282



283
284
285



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371




372

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411


412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491

492
493
494


495
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
...
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
...
562
563
564
565
566
567
568






































569
570
571
572
573
574
575
...
580
581
582
583
584
585
586
587
588
589
590
591



592

593
594
595



596
597


598
599





600





601
602
603
604
605
606
607
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table from which we should delete things */
  Expr *pWhere           /* The WHERE clause.  May be null */
){
  Vdbe *v;               /* The virtual database engine */
  Table *pTab;           /* The table from which records will be deleted */
  const char *zDb;       /* Name of database holding pTab */
  int end, addr = 0;     /* A couple addresses of generated code */
  int i;                 /* Loop counter */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int iCur;              /* VDBE Cursor number for pTab */
  sqlite4 *db;           /* Main database structure */
  AuthContext sContext;  /* Authorization context */
  NameContext sNC;       /* Name context to resolve expressions in */
................................................................................
    goto delete_from_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we
  ** will be calling are designed to work with multiple tables and expect
  ** an SrcList* parameter instead of just a Table* parameter.
  */
  pTab = sqlite4SrcListLookup(pParse, pTabList);
  if( pTab==0 )  goto delete_from_cleanup;

  /* Figure out if we have any triggers and if the table being
  ** deleted from is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
  isView = pTab->pSelect!=0;
#else
# define pTrigger 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( sqlite4ViewGetColumnNames(pParse, pTab) ){
    goto delete_from_cleanup;
  }




  if( sqlite4IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
    goto delete_from_cleanup;
  }



  iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  zDb = db->aDb[iDb].zName;
  rcauth = sqlite4AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
  assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
  if( rcauth==SQLITE_DENY ){
    goto delete_from_cleanup;
  }
  assert(!isView || pTrigger);

  /* Assign  cursor number to the table and all its indices.
  */
  assert( pTabList->nSrc==1 );
  iCur = pTabList->a[0].iCursor = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }

  /* Start the view context
................................................................................
  ** It is easier just to erase the whole table. Prior to version 3.6.5,
  ** this optimization caused the row change count (the value returned by 
  ** API function sqlite4_count_changes) to be set incorrectly.  */
  if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) 
   && 0==sqlite4FkRequired(pParse, pTab, 0, 0)
  ){
    assert( !isView );
    sqlite4VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
                      pTab->zName, P4_STATIC);
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->pSchema==pTab->pSchema );
      sqlite4VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
    }
  }else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table and pick which records to delete.
  */
  {
    int iRowSet = ++pParse->nMem;   /* Register for rowset of rows to delete */
    int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
    int regRowid;                   /* Actual register containing rowids */

    /* Collect rowids of every row to be deleted.
    */




    sqlite4VdbeAddOp2(v, OP_Null, 0, iRowSet);

    pWInfo = sqlite4WhereBegin(
        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK
    );
    if( pWInfo==0 ) goto delete_from_cleanup;
    regRowid = sqlite4ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid);
    sqlite4VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
    if( db->flags & SQLITE_CountRows ){
      sqlite4VdbeAddOp2(v, OP_AddImm, memCnt, 1);
    }
    sqlite4WhereEnd(pWInfo);

    /* Delete every item whose key was written to the list during the
    ** database scan.  We have to delete items after the scan is complete
    ** because deleting an item can change the scan order.  */
    end = sqlite4VdbeMakeLabel(v);

    /* Unless this is a view, open cursors for the table we are 
    ** deleting from and all its indices. If this is a view, then the
    ** only effect this statement has is to fire the INSTEAD OF 
    ** triggers.  */

    if( !isView ){
      sqlite4OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
    }

    addr = sqlite4VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);

    /* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
      sqlite4VtabMakeWritable(pParse, pTab);
      sqlite4VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
      sqlite4VdbeChangeP5(v, OE_Abort);
      sqlite4MayAbort(pParse);
    }else
#endif
    {
      int count = (pParse->nested==0);    /* True to count changes */
      sqlite4GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);


    }

    /* End of the delete loop */
    sqlite4VdbeAddOp2(v, OP_Goto, 0, addr);
    sqlite4VdbeResolveLabel(v, end);

    /* Close the cursors open on the table and its indexes. */
    if( !isView && !IsVirtual(pTab) ){
      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
        sqlite4VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
      }
      sqlite4VdbeAddOp1(v, OP_Close, iCur);
    }
  }

  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
................................................................................
**   3.  The record number of the row to be deleted must be stored in
**       memory cell iRowid.
**
** This routine generates code to remove both the table record and all 
** index entries that point to that record.
*/
void sqlite4GenerateRowDelete(
  Parse *pParse,     /* Parsing context */
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  int iRowid,        /* Memory cell that contains the rowid to delete */
  int count,         /* If non-zero, increment the row change counter */
  Trigger *pTrigger, /* List of triggers to (potentially) fire */
  int onconf         /* Default ON CONFLICT policy for triggers */
){
  Vdbe *v = pParse->pVdbe;        /* Vdbe */
  int iOld = 0;                   /* First register in OLD.* array */
  int iLabel;                     /* Label resolved to end of generated code */


  /* Vdbe is guaranteed to have been allocated by this stage. */
  assert( v );



  /* Seek cursor iCur to the row to delete. If this row no longer exists 
  ** (this can happen if a trigger program has already deleted it), do
  ** not attempt to delete it or fire any DELETE triggers.  */
  iLabel = sqlite4VdbeMakeLabel(v);
  sqlite4VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
 
  /* If there are any triggers to fire, allocate a range of registers to
  ** use for the old.* references in the triggers.  */

  if( sqlite4FkRequired(pParse, pTab, 0, 0) || pTrigger ){
    u32 mask;                     /* Mask of OLD.* columns in use */
    int iCol;                     /* Iterator used while populating OLD.* */

    /* TODO: Could use temporary registers here. Also could attempt to
    ** avoid copying the contents of the rowid register.  */
    mask = sqlite4TriggerColmask(
................................................................................
    sqlite4VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);

    /* Do FK processing. This call checks that any FK constraints that
    ** refer to this table (i.e. constraints attached to other tables) 
    ** are not violated by deleting this row.  */
    sqlite4FkCheck(pParse, pTab, iOld, 0);
  }


  /* Delete the index and table entries. Skip this step if pTab is really
  ** a view (in which case the only effect of the DELETE statement is to
  ** fire the INSTEAD OF triggers).  */ 
  if( pTab->pSelect==0 ){
    sqlite4GenerateRowIndexDelete(pParse, pTab, iCur, 0);
    sqlite4VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
    if( count ){
      sqlite4VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
    }

  }

  /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
  ** handle rows (possibly in other tables) that refer via a foreign key
  ** to the row just deleted. */ 
  sqlite4FkActions(pParse, pTab, 0, iOld);

................................................................................
  );

  /* Jump here if the row had already been deleted before any BEFORE
  ** trigger programs were invoked. Or if a trigger program throws a 
  ** RAISE(IGNORE) exception.  */
  sqlite4VdbeResolveLabel(v, iLabel);
}







































/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
................................................................................
**   2.  Read/write cursors for all indices of pTab must be open as
**       cursor number iCur+i for the i-th index.
**
**   3.  The "iCur" cursor must be pointing to the row that is to be
**       deleted.
*/
void sqlite4GenerateRowIndexDelete(
  Parse *pParse,     /* Parsing and code generating context */
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){



  int i;

  Index *pIdx;
  int r1;




  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;


    r1 = sqlite4GenerateIndexKey(pParse, pIdx, iCur, 0, 0, 0);
    sqlite4VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);





  }





}

/*
** Generate code that will assemble an index key and put it in register
** regOut.  The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.







|







 







|
<




|
<












|
<




>
>
>



>
>
>








<

|
<







 







<
<










|
|
|

|
|
>
>
>
>
|
>




|
|





<
<
<
<
<
|
<
<
<
>

|


|













|
>
>



|
|

|
|
<
<
<
<
<







 







|
|
|
|
|
|
|




>



>
>





|



>







 







>





|
|



>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|

>
>
>

>

<

>
>
>
|
<
>
>
|
<
>
>
>
>
>
|
>
>
>
>
>







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
...
250
251
252
253
254
255
256
257

258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298

299
300
301
302
303
304
305
...
348
349
350
351
352
353
354


355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387





388



389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418





419
420
421
422
423
424
425
...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

636
637
638
639
640

641
642
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table from which we should delete things */
  Expr *pWhere           /* The WHERE clause.  May be null */
){
  Vdbe *v;               /* The virtual database engine */
  Table *pTab;           /* The table from which records will be deleted */
  const char *zDb;       /* Name of database holding pTab */
  int addr = 0;     /* A couple addresses of generated code */
  int i;                 /* Loop counter */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int iCur;              /* VDBE Cursor number for pTab */
  sqlite4 *db;           /* Main database structure */
  AuthContext sContext;  /* Authorization context */
  NameContext sNC;       /* Name context to resolve expressions in */
................................................................................
    goto delete_from_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we
  ** will be calling are designed to work with multiple tables and expect
  ** an SrcList* parameter instead of just a Table* parameter.  */

  pTab = sqlite4SrcListLookup(pParse, pTabList);
  if( pTab==0 )  goto delete_from_cleanup;

  /* Figure out if we have any triggers and if the table being
  ** deleted from is a view.  */

#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
  isView = pTab->pSelect!=0;
#else
# define pTrigger 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  /* If pTab is really a view, make sure it has been initialized. */

  if( sqlite4ViewGetColumnNames(pParse, pTab) ){
    goto delete_from_cleanup;
  }

  /* Check the table is not read-only (e.g. sqlite_master or sqlite_stat).
  ** Also, check that if pTab is really an SQL view, one or more INSTEAD 
  ** OF DELETE triggers have been configured.  */
  if( sqlite4IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
    goto delete_from_cleanup;
  }
  assert(!isView || pTrigger);

  /* Invoke the authorization callback */
  iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  zDb = db->aDb[iDb].zName;
  rcauth = sqlite4AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
  assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
  if( rcauth==SQLITE_DENY ){
    goto delete_from_cleanup;
  }


  /* Assign  cursor number to the table and all its indices. */

  assert( pTabList->nSrc==1 );
  iCur = pTabList->a[0].iCursor = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }

  /* Start the view context
................................................................................
  ** It is easier just to erase the whole table. Prior to version 3.6.5,
  ** this optimization caused the row change count (the value returned by 
  ** API function sqlite4_count_changes) to be set incorrectly.  */
  if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) 
   && 0==sqlite4FkRequired(pParse, pTab, 0, 0)
  ){
    assert( !isView );


    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->pSchema==pTab->pSchema );
      sqlite4VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
    }
  }else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table and pick which records to delete.
  */
  {
    int regSet = ++pParse->nMem;  /* Register for rowset of rows to delete */
    int regKey = ++pParse->nMem;  /* Used for storing row keys */
    int addrTop;                  /* Instruction (KeySetRead) at top of loop */

    /* Query the table for all rows that match the WHERE clause. Store the
    ** PRIMARY KEY for each matching row in the KeySet object in register
    ** regSet. After the scan is complete, the VM will loop through the set 
    ** of keys in the KeySet and delete each row. Rows must be deleted after 
    ** the scan is complete because deleting an item can change the scan 
    ** order.  */
    sqlite4VdbeAddOp2(v, OP_Null, 0, regSet);
    VdbeComment((v, "initialize KeySet"));
    pWInfo = sqlite4WhereBegin(
        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK
    );
    if( pWInfo==0 ) goto delete_from_cleanup;
    sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
    sqlite4VdbeAddOp2(v, OP_KeySetAdd, regSet, regKey);
    if( db->flags & SQLITE_CountRows ){
      sqlite4VdbeAddOp2(v, OP_AddImm, memCnt, 1);
    }
    sqlite4WhereEnd(pWInfo);






    /* Unless this is a view, open cursors for all indexes on the table



    ** from which we are deleting.  */
    if( !isView ){
      sqlite4OpenAllIndexes(pParse, pTab, iCur, OP_OpenWrite);
    }

    addrTop = sqlite4VdbeAddOp3(v, OP_KeySetRead, regSet, 0, regKey);

    /* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
      sqlite4VtabMakeWritable(pParse, pTab);
      sqlite4VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
      sqlite4VdbeChangeP5(v, OE_Abort);
      sqlite4MayAbort(pParse);
    }else
#endif
    {
      int count = (pParse->nested==0);    /* True to count changes */
      sqlite4GenerateRowDelete(
          pParse, pTab, iCur, regKey, count, pTrigger, OE_Default
      );
    }

    /* End of the delete loop */
    sqlite4VdbeAddOp2(v, OP_Goto, 0, addrTop);
    sqlite4VdbeJumpHere(v, addrTop);

    /* Close all open cursors */
    sqlite4CloseAllIndexes(pParse, pTab, iCur);





  }

  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
................................................................................
**   3.  The record number of the row to be deleted must be stored in
**       memory cell iRowid.
**
** This routine generates code to remove both the table record and all 
** index entries that point to that record.
*/
void sqlite4GenerateRowDelete(
  Parse *pParse,                  /* Parsing context */
  Table *pTab,                    /* Table containing the row to be deleted */
  int baseCur,                    /* Base cursor number */
  int regKey,                     /* Register containing PK of row to delete */
  int bCount,                     /* True to increment the row change counter */
  Trigger *pTrigger,              /* List of triggers to (potentially) fire */
  int onconf                      /* Default ON CONFLICT policy for triggers */
){
  Vdbe *v = pParse->pVdbe;        /* Vdbe */
  int iOld = 0;                   /* First register in OLD.* array */
  int iLabel;                     /* Label resolved to end of generated code */
  int iPk;

  /* Vdbe is guaranteed to have been allocated by this stage. */
  assert( v );

  sqlite4FindPrimaryKey(pTab, &iPk);

  /* Seek cursor iCur to the row to delete. If this row no longer exists 
  ** (this can happen if a trigger program has already deleted it), do
  ** not attempt to delete it or fire any DELETE triggers.  */
  iLabel = sqlite4VdbeMakeLabel(v);
  sqlite4VdbeAddOp4(v, OP_NotFound, baseCur+iPk, iLabel, regKey, 0, P4_INT32);
 
  /* If there are any triggers to fire, allocate a range of registers to
  ** use for the old.* references in the triggers.  */
#if 0
  if( sqlite4FkRequired(pParse, pTab, 0, 0) || pTrigger ){
    u32 mask;                     /* Mask of OLD.* columns in use */
    int iCol;                     /* Iterator used while populating OLD.* */

    /* TODO: Could use temporary registers here. Also could attempt to
    ** avoid copying the contents of the rowid register.  */
    mask = sqlite4TriggerColmask(
................................................................................
    sqlite4VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);

    /* Do FK processing. This call checks that any FK constraints that
    ** refer to this table (i.e. constraints attached to other tables) 
    ** are not violated by deleting this row.  */
    sqlite4FkCheck(pParse, pTab, iOld, 0);
  }
#endif

  /* Delete the index and table entries. Skip this step if pTab is really
  ** a view (in which case the only effect of the DELETE statement is to
  ** fire the INSTEAD OF triggers).  */ 
  if( pTab->pSelect==0 ){
    sqlite4GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
#if 0
    if( count ){
      sqlite4VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
    }
#endif
  }

  /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
  ** handle rows (possibly in other tables) that refer via a foreign key
  ** to the row just deleted. */ 
  sqlite4FkActions(pParse, pTab, 0, iOld);

................................................................................
  );

  /* Jump here if the row had already been deleted before any BEFORE
  ** trigger programs were invoked. Or if a trigger program throws a 
  ** RAISE(IGNORE) exception.  */
  sqlite4VdbeResolveLabel(v, iLabel);
}

static void generateIndexKey(
  Parse *pParse,
  Index *pPk, int iPkCsr,
  Index *pIdx, int iIdxCsr,
  int regOut
){
  Vdbe *v = pParse->pVdbe;        /* VM to write code to */
  int nTmpReg;                    /* Number of temp registers required */
  int regTmp;                     /* First register in temp array */
  int i;                          /* Iterator variable */

  /* Allocate temp registers */
  assert( pIdx!=pPk );
  nTmpReg = pIdx->nColumn + pPk->nColumn;
  regTmp = sqlite4GetTempRange(pParse, nTmpReg);

  /* Assemble the values for the key in the array of temp registers */
  for(i=0; i<pIdx->nColumn; i++){
    int regVal = regTmp + i;
    sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pIdx->aiColumn[i], regVal);
  }
  for(i=0; i<pPk->nColumn; i++){
    int iCol = pPk->aiColumn[i];
    int regVal = pIdx->nColumn + regTmp + i;
    if( iCol<0 ){
      sqlite4VdbeAddOp2(v, OP_Rowid, iPkCsr, regVal);
    }else{
      sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pPk->aiColumn[i], regVal);
    }
  }

  /* Build the index key */
  sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdxCsr, regTmp, regOut);

  /* Release temp registers */
  sqlite4ReleaseTempRange(pParse, regTmp, nTmpReg);
}

/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
................................................................................
**   2.  Read/write cursors for all indices of pTab must be open as
**       cursor number iCur+i for the i-th index.
**
**   3.  The "iCur" cursor must be pointing to the row that is to be
**       deleted.
*/
void sqlite4GenerateRowIndexDelete(
  Parse *pParse,                  /* Parsing and code generating context */
  Table *pTab,                    /* Table containing the row to be deleted */
  int baseCur,                    /* Cursor number for the table */
  int *aRegIdx                    /* Only delete if (aRegIdx && aRegIdx[i]>0) */
){
  Vdbe *v = pParse->pVdbe;
  Index *pPk;
  int iPk;
  int i;
  int regKey;
  Index *pIdx;


  regKey = sqlite4GetTempReg(pParse);
  pPk = sqlite4FindPrimaryKey(pTab, &iPk);

  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){

    if( pIdx!=pPk && (aRegIdx==0 || aRegIdx[i]>0) ){
      int addrNotFound;
      generateIndexKey(pParse, pPk, baseCur+iPk, pIdx, baseCur+i, regKey);

      addrNotFound = sqlite4VdbeAddOp4(v,
          OP_NotFound, baseCur+i, 0, regKey, 0, P4_INT32
      );
      sqlite4VdbeAddOp1(v, OP_Delete, baseCur+i);
      sqlite4VdbeJumpHere(v, addrNotFound);
    }
  }

  sqlite4VdbeAddOp1(v, OP_Delete, baseCur+iPk);

  sqlite4ReleaseTempReg(pParse, regKey);
}

/*
** Generate code that will assemble an index key and put it in register
** regOut.  The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.

Changes to src/fkey.c.

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      ** of columns. If each indexed column corresponds to a foreign key
      ** column of pFKey, then this index is a winner.  */

      if( zKey==0 ){
        /* If zKey is NULL, then this foreign key is implicitly mapped to 
        ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be 
        ** identified by the test (Index.autoIndex==2).  */
        if( pIdx->autoIndex==2 ){
          if( aiCol ){
            int i;
            for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
          }
          break;
        }
      }else{







|







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      ** of columns. If each indexed column corresponds to a foreign key
      ** column of pFKey, then this index is a winner.  */

      if( zKey==0 ){
        /* If zKey is NULL, then this foreign key is implicitly mapped to 
        ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be 
        ** identified by the test (Index.autoIndex==2).  */
        if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
          if( aiCol ){
            int i;
            for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
          }
          break;
        }
      }else{

Changes to src/insert.c.

20
21
22
23
24
25
26
27
28






29









30
31






32
33
34






















35
36
37
38
39
40




41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69


















70
71

72
73
74








75
76


77
78

79
80
81
82
83
84
85
86
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
460
461
462
463
464
465
466
467
468
469
470







471
472
473
474
475
476
477
...
493
494
495
496
497
498
499




500
501
502
503
504
505
506
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
...
639
640
641
642
643
644
645

646
647
648
649
650
651
652
...
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752







753
754
755
756
757
758
759
760
761
762
763
764
...
788
789
790
791
792
793
794
795
796
797


798
799

800


801
802
803
804
805
806
807
808
809
810
811
...
869
870
871
872
873
874
875
876
877
878
879
880
881







882
883
884
885
886
887
888
...
918
919
920
921
922
923
924

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
...
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
....
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
....
1055
1056
1057
1058
1059
1060
1061









1062

































































































1063








































1064
1065
1066
1067
1068
1069
1070
....
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143

1144
1145

1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166

1167


1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316



1317
1318
1319
1320



1321

1322
1323
1324
1325
1326




1327
1328
1329
1330
1331
1332
1333
1334

1335
1336




1337
1338
1339
1340

1341







1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393


1394
1395
1396
1397
1398
1399
1400
1401
1402
1403

1404
1405
1406


1407


1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423











1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443

1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475







1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

1492




















1493
1494
1495
1496
1497



1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
void sqlite4OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite4.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Vdbe *v;
  if( IsVirtual(pTab) ) return;






  v = sqlite4GetVdbe(p);









  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite4TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);






  sqlite4VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
  sqlite4VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
  VdbeComment((v, "%s", pTab->zName));






















}

/*
** Return a pointer to the column affinity string associated with index
** pIdx. A column affinity string has one character for each column in 
** the table, according to the affinity of the column:




**
**  Character      Column affinity
**  ------------------------------
**  'a'            TEXT
**  'b'            NONE
**  'c'            NUMERIC
**  'd'            INTEGER
**  'e'            REAL
**
** An extra 'd' is appended to the end of the string to cover the
** rowid that appears as the last column in every index.
**
** Memory for the buffer containing the column index affinity string
** is managed along with the rest of the Index structure. It will be
** released when sqlite4DeleteIndex() is called.
*/
const char *sqlite4IndexAffinityStr(Vdbe *v, Index *pIdx){
  if( !pIdx->zColAff ){
    /* The first time a column affinity string for a particular index is
    ** required, it is allocated and populated here. It is then stored as
    ** a member of the Index structure for subsequent use.
    **
    ** The column affinity string will eventually be deleted by
    ** sqliteDeleteIndex() when the Index structure itself is cleaned
    ** up.
    */
    int n;
    Table *pTab = pIdx->pTable;

    sqlite4 *db = sqlite4VdbeDb(v);


















    pIdx->zColAff = (char *)sqlite4DbMallocRaw(0, pIdx->nColumn+2);
    if( !pIdx->zColAff ){

      db->mallocFailed = 1;
      return 0;
    }








    for(n=0; n<pIdx->nColumn; n++){
      pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;


    }
    pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;

    pIdx->zColAff[n] = 0;
  }
 
  return pIdx->zColAff;
}

/*
** Set P4 of the most recently inserted opcode to a column affinity
................................................................................

  for(i=iStartAddr; i<iEnd; i++){
    VdbeOp *pOp = sqlite4VdbeGetOp(v, i);
    assert( pOp!=0 );
    if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
      Index *pIndex;
      int tnum = pOp->p2;
      if( tnum==pTab->tnum ){
        return 1;
      }
      for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
        if( tnum==pIndex->tnum ){
          return 1;
        }
      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  int appendFlag = 0;   /* True if the insert is likely to be an append */

  /* Register allocations */
  int regFromSelect = 0;/* Base register for data coming from SELECT */
  int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
  int regRowCount = 0;  /* Memory cell used for the row counter */
  int regIns;           /* Block of regs holding rowid+data being inserted */
  int regRowid;         /* registers holding insert rowid */
  int regData;          /* register holding first column to insert */
  int regEof = 0;       /* Register recording end of SELECT data */
  int *aRegIdx = 0;     /* One register allocated to each index */








#ifndef SQLITE_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  Trigger *pTrigger;          /* List of triggers on pTab, if required */
  int tmask;                  /* Mask of trigger times */
#endif

................................................................................
  iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  pDb = &db->aDb[iDb];
  zDb = pDb->zName;
  if( sqlite4AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
    goto insert_cleanup;
  }





  /* Figure out if we have any triggers and if the table being
  ** inserted into is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
  isView = pTab->pSelect!=0;
................................................................................
# undef isView
# define isView 0
#endif
  assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );

  /* If pTab is really a view, make sure it has been initialized.
  ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual 
  ** module table).
  */
  if( sqlite4ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }

  /* Ensure that:
  *  (a) the table is not read-only, 
  *  (b) that if it is a view then ON INSERT triggers exist
  */
  if( sqlite4IsReadOnly(pParse, pTab, tmask) ){
    goto insert_cleanup;
  }

  /* Allocate a VDBE
  */
  v = sqlite4GetVdbe(pParse);
  if( v==0 ) goto insert_cleanup;
  if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
  sqlite4BeginWriteOperation(pParse, pSelect || pTrigger, iDb);

#ifndef SQLITE_OMIT_XFER_OPT
  /* If the statement is of the form
................................................................................
  if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
    assert( !pTrigger );
    assert( pList==0 );
    goto insert_end;
  }
#endif /* SQLITE_OMIT_XFER_OPT */

  /* If this is an AUTOINCREMENT table, look up the sequence number in the
  ** sqlite_sequence table and store it in memory cell regAutoinc.
  */
  regAutoinc = autoIncBegin(pParse, iDb, pTab);

  /* Figure out how many columns of data are supplied.  If the data
  ** is coming from a SELECT statement, then generate a co-routine that
  ** produces a single row of the SELECT on each invocation.  The
  ** co-routine is the common header to the 3rd and 4th templates.
  */
  if( pSelect ){
    /* Data is coming from a SELECT.  Generate code to implement that SELECT
................................................................................
      **         if EOF goto M
      **         insert row from R..R+n into temp table
      **         goto L
      **      M: ...
      */
      int regRec;          /* Register to hold packed record */
      int regTempRowid;    /* Register to hold temp table ROWID */

      int addrTop;         /* Label "L" */
      int addrIf;          /* Address of jump to M */

      srcTab = pParse->nTab++;
      regRec = sqlite4GetTempReg(pParse);
      regTempRowid = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
................................................................................
      sqlite4VdbeAddOp2(v, OP_Goto, 0, addrTop);
      sqlite4VdbeJumpHere(v, addrIf);
      sqlite4ReleaseTempReg(pParse, regRec);
      sqlite4ReleaseTempReg(pParse, regTempRowid);
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
    ** clause
    */
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    srcTab = -1;
    assert( useTempTable==0 );
    nColumn = pList ? pList->nExpr : 0;
    for(i=0; i<nColumn; i++){
................................................................................
  */
  if( IsVirtual(pTab) ){
    for(i=0; i<pTab->nCol; i++){
      nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
    }
  }
  if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
    sqlite4ErrorMsg(pParse, 
       "table %S has %d columns but %d values were supplied",
       pTabList, 0, pTab->nCol-nHidden, nColumn);
    goto insert_cleanup;
  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    sqlite4ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
    goto insert_cleanup;
  }

  /* If the INSERT statement included an IDLIST term, then make sure
  ** all elements of the IDLIST really are columns of the table and 
  ** remember the column indices.
  **
  ** If the table has an INTEGER PRIMARY KEY column and that column
  ** is named in the IDLIST, then record in the keyColumn variable
  ** the index into IDLIST of the primary key column.  keyColumn is
  ** the index of the primary key as it appears in IDLIST, not as
  ** is appears in the original table.  (The index of the primary
  ** key in the original table is pTab->iPKey.)
  */
  if( pColumn ){
    for(i=0; i<pColumn->nId; i++){
      pColumn->a[i].idx = -1;
    }
    for(i=0; i<pColumn->nId; i++){

      for(j=0; j<pTab->nCol; j++){
        if( sqlite4StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
          pColumn->a[i].idx = j;
          if( j==pTab->iPKey ){
            keyColumn = i;
          }
          break;
        }
      }
      if( j>=pTab->nCol ){
        if( sqlite4IsRowid(pColumn->a[i].zName) ){
          keyColumn = i;
        }else{
          sqlite4ErrorMsg(pParse, "table %S has no column named %s",
              pTabList, 0, pColumn->a[i].zName);
          pParse->checkSchema = 1;
          goto insert_cleanup;
        }
      }
    }
  }

  /* If there is no IDLIST term but the table has an integer primary
  ** key, the set the keyColumn variable to the primary key column index
  ** in the original table definition.
  */
  if( pColumn==0 && nColumn>0 ){
    keyColumn = pTab->iPKey;
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( db->flags & SQLITE_CountRows ){
    regRowCount = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  /* If this is not a view, open the table and and all indices */







  if( !isView ){
    int nIdx;

    baseCur = pParse->nTab;
    nIdx = sqlite4OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
    aRegIdx = sqlite4DbMallocRaw(db, sizeof(int)*(nIdx+1));
    if( aRegIdx==0 ){
      goto insert_cleanup;
    }
    for(i=0; i<nIdx; i++){
      aRegIdx[i] = ++pParse->nMem;  /* Register in which to store key */
      pParse->nMem++;               /* Extra register for data */
................................................................................
    **         goto C
    **      D: ...
    */
    addrCont = sqlite4VdbeAddOp1(v, OP_Yield, dest.iParm);
    addrInsTop = sqlite4VdbeAddOp1(v, OP_If, regEof);
  }

  /* Allocate registers for holding the rowid of the new row,
  ** the content of the new row, and the assemblied row record.
  */


  regRowid = regIns = pParse->nMem+1;
  pParse->nMem += pTab->nCol + 1;

  if( IsVirtual(pTab) ){


    regRowid++;
    pParse->nMem++;
  }
  regData = regRowid+1;

  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite4VdbeMakeLabel(v);
  if( tmask & TRIGGER_BEFORE ){
    int regCols = sqlite4GetTempRange(pParse, pTab->nCol+1);

................................................................................
    /* Fire BEFORE or INSTEAD OF triggers */
    sqlite4CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, regCols-pTab->nCol-1, onError, endOfLoop);

    sqlite4ReleaseTempRange(pParse, regCols, pTab->nCol+1);
  }

  /* Push the record number for the new entry onto the stack.  The
  ** record number is a randomly generate integer created by NewRowid
  ** except when the table has an INTEGER PRIMARY KEY column, in which
  ** case the record number is the same as that column. 
  */
  if( !isView ){







    if( IsVirtual(pTab) ){
      /* The row that the VUpdate opcode will delete: none */
      sqlite4VdbeAddOp2(v, OP_Null, 0, regIns);
    }
    if( keyColumn>=0 ){
      if( useTempTable ){
        sqlite4VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
................................................................................
    }else if( IsVirtual(pTab) ){
      sqlite4VdbeAddOp2(v, OP_Null, 0, regRowid);
    }else{
      sqlite4VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
      appendFlag = 1;
    }
    autoIncStep(pParse, regAutoinc, regRowid);


    /* Push onto the stack, data for all columns of the new entry, beginning
    ** with the first column.
    */
    nHidden = 0;
    for(i=0; i<pTab->nCol; i++){
      int iRegStore = regRowid+1+i;
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the record number will be substituted
        ** in its place.  So will fill this column with a NULL to avoid
        ** taking up data space with information that will never be used. */
        sqlite4VdbeAddOp2(v, OP_Null, 0, iRegStore);
        continue;
      }
      if( pColumn==0 ){
        if( IsHiddenColumn(&pTab->aCol[i]) ){
          assert( IsVirtual(pTab) );
          j = -1;
          nHidden++;
        }else{
          j = i - nHidden;
................................................................................
      sqlite4VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
      sqlite4VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
      sqlite4MayAbort(pParse);
    }else
#endif
    {
      int isReplace;    /* Set to true if constraints may cause a replace */
      sqlite4GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
          keyColumn>=0, 0, onError, endOfLoop, &isReplace
      );
      sqlite4FkCheck(pParse, pTab, 0, regIns);
      sqlite4CompleteInsertion(
          pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
      );
    }
  }

  /* Update the count of rows that are inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0 ){
................................................................................
  }else if( pSelect ){
    sqlite4VdbeAddOp2(v, OP_Goto, 0, addrCont);
    sqlite4VdbeJumpHere(v, addrInsTop);
  }

  if( !IsVirtual(pTab) && !isView ){
    /* Close all tables opened */
    sqlite4VdbeAddOp1(v, OP_Close, baseCur);
    for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
      sqlite4VdbeAddOp1(v, OP_Close, idx+baseCur);
    }
  }

insert_end:
  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
................................................................................
#ifdef pTrigger
 #undef pTrigger
#endif
#ifdef tmask
 #undef tmask
#endif












































































































/*








































** Generate code to do constraint checks prior to an INSERT or an UPDATE.
**
** The input is a range of consecutive registers as follows:
**
**    1.  The rowid of the row after the update.
**
**    2.  The data in the first column of the entry after the update.
................................................................................
** read/write cursors with cursor number baseCur+i for the i-th cursor.
** Except, if there is no possibility of a REPLACE action then
** cursors do not need to be open for indices where aRegIdx[i]==0.
*/
void sqlite4GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* Index of a read/write cursor pointing at pTab */
  int regRowid,       /* Index of the range of input registers */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */

  int rowidChng,      /* True if the rowid might collide with existing entry */
  int isUpdate,       /* True for UPDATE, False for INSERT */

  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest,     /* Jump to this label on an OE_Ignore resolution */
  int *pbMayReplace   /* OUT: Set to true if constraint may cause a replace */
){

  int i;              /* loop counter */
  Vdbe *v;            /* VDBE under constrution */
  int nCol;           /* Number of columns */
  int onError;        /* Conflict resolution strategy */
  int j1;             /* Addresss of jump instruction */
  int j2 = 0, j3;     /* Addresses of jump instructions */
  int regData;        /* Register containing first data column */
  int iCur;           /* Table cursor number */
  Index *pIdx;         /* Pointer to one of the indices */
  int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;

  v = sqlite4GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;
  regData = regRowid + 1;




  /* Test all NOT NULL constraints.
  */
  for(i=0; i<nCol; i++){
    if( i==pTab->iPKey ){
      continue;
    }
    onError = pTab->aCol[i].notNull;
    if( onError==OE_None ) continue;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
      onError = OE_Abort;
    }
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Abort:
        sqlite4MayAbort(pParse);
      case OE_Rollback:
      case OE_Fail: {
        char *zMsg;
        sqlite4VdbeAddOp3(v, OP_HaltIfNull,
                                  SQLITE_CONSTRAINT, onError, regData+i);
        zMsg = sqlite4MPrintf(pParse->db, "%s.%s may not be NULL",
                              pTab->zName, pTab->aCol[i].zName);
        sqlite4VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
        break;
      }
      case OE_Ignore: {
        sqlite4VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
        break;
      }
      default: {
        assert( onError==OE_Replace );
        j1 = sqlite4VdbeAddOp1(v, OP_NotNull, regData+i);
        sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
        sqlite4VdbeJumpHere(v, j1);
        break;
      }
    }
  }

  /* Test all CHECK constraints
  */
#ifndef SQLITE_OMIT_CHECK
  if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
    int allOk = sqlite4VdbeMakeLabel(v);
    pParse->ckBase = regData;
    sqlite4ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
    if( onError==OE_Ignore ){
      sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
    }else{
      if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
      sqlite4HaltConstraint(pParse, onError, 0, 0);

    }
    sqlite4VdbeResolveLabel(v, allOk);
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
  */
  if( rowidChng ){
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
    if( isUpdate ){
      j2 = sqlite4VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
    }
    j3 = sqlite4VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
    switch( onError ){
      default: {
        onError = OE_Abort;
        /* Fall thru into the next case */
      }
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        sqlite4HaltConstraint(
          pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
        break;
      }
      case OE_Replace: {
        /* If there are DELETE triggers on this table and the
        ** recursive-triggers flag is set, call GenerateRowDelete() to
        ** remove the conflicting row from the the table. This will fire
        ** the triggers and remove both the table and index b-tree entries.
        **
        ** Otherwise, if there are no triggers or the recursive-triggers
        ** flag is not set, but the table has one or more indexes, call 
        ** GenerateRowIndexDelete(). This removes the index b-tree entries 
        ** only. The table b-tree entry will be replaced by the new entry 
        ** when it is inserted.  
        **
        ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called,
        ** also invoke MultiWrite() to indicate that this VDBE may require
        ** statement rollback (if the statement is aborted after the delete
        ** takes place). Earlier versions called sqlite4MultiWrite() regardless,
        ** but being more selective here allows statements like:
        **
        **   REPLACE INTO t(rowid) VALUES($newrowid)
        **
        ** to run without a statement journal if there are no indexes on the
        ** table.
        */
        Trigger *pTrigger = 0;
        if( pParse->db->flags&SQLITE_RecTriggers ){
          pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
        }
        if( pTrigger || sqlite4FkRequired(pParse, pTab, 0, 0) ){
          sqlite4MultiWrite(pParse);
          sqlite4GenerateRowDelete(
              pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
          );
        }else if( pTab->pIndex ){
          sqlite4MultiWrite(pParse);
          sqlite4GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    sqlite4VdbeJumpHere(v, j3);
    if( isUpdate ){
      sqlite4VdbeJumpHere(v, j2);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
    int regIdx;
    int regR;




    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */

    /* Create a key for accessing the index entry */



    regIdx = sqlite4GetTempRange(pParse, pIdx->nColumn+1);

    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite4VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
      }else{




        sqlite4VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
      }
    }
    sqlite4VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
    sqlite4VdbeAddOp2(v, OP_MakeKey, baseCur+iCur+1, aRegIdx[iCur]+1);
    sqlite4VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
    sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v, pIdx), P4_TRANSIENT);
    sqlite4ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);


    /* Find out what action to take in case there is an indexing conflict */




    onError = pIdx->onError;
    if( onError==OE_None ){ 
      sqlite4ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
      continue;  /* pIdx is not a UNIQUE index */

    }







    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( seenReplace ){
      if( onError==OE_Ignore ) onError = OE_Replace;
      else if( onError==OE_Fail ) onError = OE_Abort;
    }
    
    /* Check to see if the new index entry will be unique */
    regR = sqlite4GetTempReg(pParse);
    sqlite4VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
    j3 = sqlite4VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
                           regR, SQLITE_INT_TO_PTR(regIdx),
                           P4_INT32);
    sqlite4ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);

    /* Generate code that executes if the new index entry is not unique */
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        int j;
        StrAccum errMsg;
        const char *zSep;
        char *zErr;

        sqlite4StrAccumInit(&errMsg, 0, 0, 200);
        errMsg.db = pParse->db;
        zSep = pIdx->nColumn>1 ? "columns " : "column ";
        for(j=0; j<pIdx->nColumn; j++){
          char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;

          sqlite4StrAccumAppend(&errMsg, zSep, -1);
          zSep = ", ";
          sqlite4StrAccumAppend(&errMsg, zCol, -1);
        }
        sqlite4StrAccumAppend(&errMsg,
            pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
        zErr = sqlite4StrAccumFinish(&errMsg);
        sqlite4HaltConstraint(pParse, onError, zErr, 0);
        sqlite4DbFree(errMsg.db, zErr);
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
      default: {


        Trigger *pTrigger = 0;
        assert( onError==OE_Replace );
        sqlite4MultiWrite(pParse);
        if( pParse->db->flags&SQLITE_RecTriggers ){
          pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
        }
        sqlite4GenerateRowDelete(
            pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
        );
        seenReplace = 1;

        break;
      }
    }


    sqlite4VdbeJumpHere(v, j3);


    sqlite4ReleaseTempReg(pParse, regR);
  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite4GenerateConstraintChecks.
** A consecutive range of registers starting at regRowid contains the
** rowid and the content to be inserted.
**
** The arguments to this routine should be the same as the first six
** arguments to sqlite4GenerateConstraintChecks.











*/
void sqlite4CompleteInsertion(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* Index of a read/write cursor pointing at pTab */
  int regRowid,       /* Range of content */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int appendBias,     /* True if this is likely to be an append */
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  int i;
  Vdbe *v;
  int nIdx;
  Index *pIdx;
  u8 pik_flags;
  int regData;
  int regRec;

  v = sqlite4GetVdbe(pParse);

  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  for(i=nIdx-1; i>=0; i--){
    if( aRegIdx[i]==0 ) continue;
    sqlite4VdbeAddOp3(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i], aRegIdx[i]+1);
    if( useSeekResult ){
      sqlite4VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
    }
  }
  regData = regRowid + 1;
  regRec = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
  sqlite4TableAffinityStr(v, pTab);
  sqlite4ExprCacheAffinityChange(pParse, regData, pTab->nCol);
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE;
    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
  }
  if( appendBias ){
    pik_flags |= OPFLAG_APPEND;
  }
  if( useSeekResult ){
    pik_flags |= OPFLAG_USESEEKRESULT;
  }
  sqlite4VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
  if( !pParse->nested ){
    sqlite4VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
  }
  sqlite4VdbeChangeP5(v, pik_flags);







}

/*
** Generate code that will open cursors for a table and for all
** indices of that table.  The "baseCur" parameter is the cursor number used
** for the table.  Indices are opened on subsequent cursors.
**
** Return the number of indices on the table.
*/
int sqlite4OpenTableAndIndices(
  Parse *pParse,   /* Parsing context */
  Table *pTab,     /* Table to be opened */
  int baseCur,     /* Cursor number assigned to the table */
  int op           /* OP_OpenRead or OP_OpenWrite */
){
  int i;

  int iDb;




















  Index *pIdx;
  Vdbe *v;

  if( IsVirtual(pTab) ) return 0;
  iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);



  v = sqlite4GetVdbe(pParse);
  assert( v!=0 );
  sqlite4OpenTable(pParse, baseCur, iDb, pTab, op);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIdx);
    assert( pIdx->pSchema==pTab->pSchema );
    sqlite4VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb,
                      (char*)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pIdx->zName));
  }
  if( pParse->nTab<baseCur+i ){
    pParse->nTab = baseCur+i;
  }
  return i-1;
}


#ifdef SQLITE_TEST
/*
** The following global variable is incremented whenever the
** transfer optimization is used.  This is used for testing







|
<
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>

<
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
>
>
>
>









<
<
<





<
|
|
|
<
|
|
<
<
<
<
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>



>
>
>
>
>
>
>
>
|
<
>
>
|
<
>
|







 







<
<
<







 







<



>
>
>
>
>
>
>







 







>
>
>
>







 







|
<





|
|





|
<







 







<
<
<
<
<







 







>







 







|
|







 







|










|
|
|
<
<
<
<
<
<






>

|

<
<
<



|
<
<
<
|

|
|
<




<
<
<
<
<
<
<
<







|
>
>
>
>
>
>
>




|







 







|
|
|
>
>
|
|
>

>
>



<







 







<
<
<
<
<

>
>
>
>
>
>
>







 







>






|
<
<
<
<
<
<
<
<







 







|
|


|
|







 







<
|







 







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

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|

>


>




>




<
<
<



<





<
>

>
>
|
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
>
>
>



|
>
>
>
|
>


<
|
<
>
>
>
>
|


<
<
|
|
<
>

<
>
>
>
>

|
<
<
>
|
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|

|
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
>
|
|
|
>
>
|
>
>
|










<
<
<


>
>
>
>
>
>
>
>
>
>
>





|







<


<



>


<
<
<
<
<
<
|
<
<
<
<
<
<



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









|





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



|
|
>
>
>

<
<
|
<
|
<
<
<

<
<
<
<







20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94



95
96
97
98
99

100
101
102

103
104




105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141

142
143
144
145
146
147
148
149
150
...
207
208
209
210
211
212
213



214
215
216
217
218
219
220
...
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
...
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
...
620
621
622
623
624
625
626





627
628
629
630
631
632
633
...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
...
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767






768
769
770
771
772
773
774
775
776
777



778
779
780
781



782
783
784
785

786
787
788
789








790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
...
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867
...
925
926
927
928
929
930
931





932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
...
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990








991
992
993
994
995
996
997
....
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
....
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
1073
....
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
....
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352



1353
1354
1355

1356
1357
1358
1359
1360

1361
1362
1363
1364
1365

1366


1367







































1368












1369
1370



















































































1371
1372
1373
1374
1375


1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389

1390

1391
1392
1393
1394
1395
1396
1397


1398
1399

1400
1401

1402
1403
1404
1405
1406
1407


1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426











1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439

1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489



1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515

1516
1517

1518
1519
1520
1521
1522
1523






1524






1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595


1596

1597



1598




1599
1600
1601
1602
1603
1604
1605
void sqlite4OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite4.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  assert( 0 );

}

/*
** Open VDBE cursor iCur to access index pIdx. pIdx is guaranteed to be
** a part of database iDb.
*/
void sqlite4OpenIndex(
  Parse *p,                       /* Current parser context */
  int iCur,                       /* The cursor number of the cursor to open */
  int iDb,                        /* The database index in sqlite4.aDb[] */
  Index *pIdx,                    /* The index to be opened */
  int opcode                      /* OP_OpenRead or OP_OpenWrite */
){
  KeyInfo *pKey;                /* KeyInfo structure describing PK index */
  Vdbe *v;                      /* VM to write code into */

  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );

  assert( pIdx->tnum>0 );

  v = sqlite4GetVdbe(p);
  pKey = sqlite4IndexKeyinfo(p, pIdx);
  testcase( pKey==0 );

  sqlite4VdbeAddOp3(v, opcode, iCur, pIdx->tnum, iDb);
  sqlite4VdbeChangeP4(v, -1, (const char *)pKey, P4_KEYINFO_HANDOFF);
  VdbeComment((v, "%s", pIdx->zName));
}

/*
** Generate code that will open the primary key of a table for either 
** reading (if opcode==OP_OpenRead) or writing (if opcode==OP_OpenWrite).
*/
void sqlite4OpenPrimaryKey(
  Parse *p,                       /* Current parser context */
  int iCur,                       /* The cursor number of the cursor to open */
  int iDb,                        /* The database index in sqlite4.aDb[] */
  Table *pTab,                    /* The table to be opened */
  int opcode                      /* OP_OpenRead or OP_OpenWrite */
){
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  if( IsVirtual(pTab)==0 ){
    Index *pIdx;                  /* PRIMARY KEY index for table pTab */

    pIdx = sqlite4FindPrimaryKey(pTab, 0);
    sqlite4TableLock(p, iDb, pIdx->tnum, (opcode==OP_OpenWrite), pTab->zName);
    sqlite4OpenIndex(p, iCur, iDb, pIdx, opcode);
    assert( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY );
  }
}

/*
** Return a pointer to the column affinity string associated with index
** pIdx. A column affinity string has one character for each column in 
** the index key. If the index is the PRIMARY KEY of its table, the key
** consists of the index columns only. Otherwise, it consists of the
** indexed columns, followed by the columns that make up the tables PRIMARY
** KEY. For each column in the index key, the corresponding character of
** the affinity string is set according to the column affinity, as follows:
**
**  Character      Column affinity
**  ------------------------------
**  'a'            TEXT
**  'b'            NONE
**  'c'            NUMERIC
**  'd'            INTEGER
**  'e'            REAL
**



** Memory for the buffer containing the column index affinity string
** is managed along with the rest of the Index structure. It will be
** released when sqlite4DeleteIndex() is called.
*/
const char *sqlite4IndexAffinityStr(Vdbe *v, Index *pIdx){

  /* The first time a column affinity string for a particular index is
  ** required, it is allocated and populated here. It is then stored as
  ** a member of the Index structure for subsequent use. The column 

  ** affinity string will eventually be deleted by sqliteDeleteIndex() 
  ** when the Index structure itself is cleaned up.  */




  if( !pIdx->zColAff ){
    sqlite4 *db = sqlite4VdbeDb(v);
    Table *pTab = pIdx->pTable;   /* Table pIdx is attached to */
    int n;                        /* Iterator variable for zAff */
    Index *pPk;                   /* Primary key on same table as pIdx */
    Index *p;                     /* Iterator variable */
    char *zAff;                   /* Affinity string to populate and return */
    int nAff;                     /* Characters in zAff */

    /* Determine how many characters are in the affinity string. There is
    ** one character for each indexed column, and, if the index is not itself
    ** the primary key, one character for each column in the primary key
    ** of the table pIdx indexes.  */ 
    nAff = pIdx->nColumn;
    pPk = sqlite4FindPrimaryKey(pTab, 0);
    if( pIdx!=pPk ){
      nAff += pPk->nColumn;
    }

    /* Allocate space for the affinity string */
    zAff = pIdx->zColAff = (char *)sqlite4DbMallocRaw(0, nAff+1);

    if( !zAff ){
      db->mallocFailed = 1;
      return 0;
    }

    /* Populate the affinity string. This loop runs either once or twice.
    ** The first iteration populates zAff with affinities according to the
    ** columns indexed by pIdx.  If pIdx is not itself the table's primary 
    ** key, then the second iteration of the loop adds the primary key 
    ** columns to zAff.  */
    for(n=0, p=pIdx; p; p=(p==pPk ? 0 : pPk)){
      int i;
      for(i=0; i<p->nColumn; i++){

        int iCol = p->aiColumn[i];
        zAff[n++] = (iCol<0) ? SQLITE_AFF_INTEGER : pTab->aCol[iCol].affinity;
      }

    }
    zAff[n] = 0;
  }
 
  return pIdx->zColAff;
}

/*
** Set P4 of the most recently inserted opcode to a column affinity
................................................................................

  for(i=iStartAddr; i<iEnd; i++){
    VdbeOp *pOp = sqlite4VdbeGetOp(v, i);
    assert( pOp!=0 );
    if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
      Index *pIndex;
      int tnum = pOp->p2;



      for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
        if( tnum==pIndex->tnum ){
          return 1;
        }
      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  int appendFlag = 0;   /* True if the insert is likely to be an append */

  /* Register allocations */
  int regFromSelect = 0;/* Base register for data coming from SELECT */
  int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
  int regRowCount = 0;  /* Memory cell used for the row counter */
  int regIns;           /* Block of regs holding rowid+data being inserted */

  int regData;          /* register holding first column to insert */
  int regEof = 0;       /* Register recording end of SELECT data */
  int *aRegIdx = 0;     /* One register allocated to each index */

  int iPk;                        /* Cursor offset of PK index cursor */
  Index *pPk;                     /* Primary key for table pTab */
  int bImplicitPK;                /* True if table pTab has an implicit PK */
  int regContent;                 /* First register in column value array */
  int regRowid;                   /* If bImplicitPK, register holding IPK */


#ifndef SQLITE_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  Trigger *pTrigger;          /* List of triggers on pTab, if required */
  int tmask;                  /* Mask of trigger times */
#endif

................................................................................
  iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  pDb = &db->aDb[iDb];
  zDb = pDb->zName;
  if( sqlite4AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
    goto insert_cleanup;
  }

  /* Set bImplicitPK to true for an implicit PRIMARY KEY, or false otherwise */
  pPk = sqlite4FindPrimaryKey(pTab, &iPk);
  bImplicitPK = pPk->aiColumn[0]==-1;

  /* Figure out if we have any triggers and if the table being
  ** inserted into is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
  isView = pTab->pSelect!=0;
................................................................................
# undef isView
# define isView 0
#endif
  assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );

  /* If pTab is really a view, make sure it has been initialized.
  ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual 
  ** module table).  */

  if( sqlite4ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }

  /* Ensure that:
  **   (a) the table is not read-only (e.g. sqlite_master, sqlite_stat), and
  **   (b) that if it is a view then ON INSERT triggers exist
  */
  if( sqlite4IsReadOnly(pParse, pTab, tmask) ){
    goto insert_cleanup;
  }

  /* Allocate a VDBE and begin a write transaction */

  v = sqlite4GetVdbe(pParse);
  if( v==0 ) goto insert_cleanup;
  if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
  sqlite4BeginWriteOperation(pParse, pSelect || pTrigger, iDb);

#ifndef SQLITE_OMIT_XFER_OPT
  /* If the statement is of the form
................................................................................
  if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
    assert( !pTrigger );
    assert( pList==0 );
    goto insert_end;
  }
#endif /* SQLITE_OMIT_XFER_OPT */






  /* Figure out how many columns of data are supplied.  If the data
  ** is coming from a SELECT statement, then generate a co-routine that
  ** produces a single row of the SELECT on each invocation.  The
  ** co-routine is the common header to the 3rd and 4th templates.
  */
  if( pSelect ){
    /* Data is coming from a SELECT.  Generate code to implement that SELECT
................................................................................
      **         if EOF goto M
      **         insert row from R..R+n into temp table
      **         goto L
      **      M: ...
      */
      int regRec;          /* Register to hold packed record */
      int regTempRowid;    /* Register to hold temp table ROWID */
      int regTempKey;      /* Register to hold key encoded rowid */
      int addrTop;         /* Label "L" */
      int addrIf;          /* Address of jump to M */

      srcTab = pParse->nTab++;
      regRec = sqlite4GetTempReg(pParse);
      regTempRowid = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
................................................................................
      sqlite4VdbeAddOp2(v, OP_Goto, 0, addrTop);
      sqlite4VdbeJumpHere(v, addrIf);
      sqlite4ReleaseTempReg(pParse, regRec);
      sqlite4ReleaseTempReg(pParse, regTempRowid);
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
    ** (or DEFAULT VALUES) clause. Resolve all references in the VALUES(...)
    ** expressions.  */ 
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    srcTab = -1;
    assert( useTempTable==0 );
    nColumn = pList ? pList->nExpr : 0;
    for(i=0; i<nColumn; i++){
................................................................................
  */
  if( IsVirtual(pTab) ){
    for(i=0; i<pTab->nCol; i++){
      nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
    }
  }
  if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
    sqlite4ErrorMsg(pParse,
       "table %S has %d columns but %d values were supplied",
       pTabList, 0, pTab->nCol-nHidden, nColumn);
    goto insert_cleanup;
  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    sqlite4ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
    goto insert_cleanup;
  }

  /* If the INSERT statement included an IDLIST term, then make sure
  ** all elements of the IDLIST really are columns of the table. Set
  ** the pColumn->a[iCol].idx variables to indicate which column of the
  ** table each IDLIST element corresponds to.






  */
  if( pColumn ){
    for(i=0; i<pColumn->nId; i++){
      pColumn->a[i].idx = -1;
    }
    for(i=0; i<pColumn->nId; i++){
      char *zTest = pColumn->a[i].zName;
      for(j=0; j<pTab->nCol; j++){
        if( sqlite4StrICmp(zTest, pTab->aCol[j].zName)==0 ){
          pColumn->a[i].idx = j;



          break;
        }
      }
      if( j==pTab->nCol ){



        sqlite4ErrorMsg(pParse, "table %S has no column named %s",
              pTabList, 0, pColumn->a[i].zName);
        pParse->checkSchema = 1;
        goto insert_cleanup;

      }
    }
  }









  /* Initialize the count of rows to be inserted
  */
  if( db->flags & SQLITE_CountRows ){
    regRowCount = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  /* If this is not a view, open a write cursor on each index. Allocate
  ** a contiguous array of (nIdx+1) registers, where nIdx is the total
  ** number of indexes (including the PRIMARY KEY index). 
  **
  **   Register aRegIdx[0]:         The PRIMARY KEY index key
  **   Register aRegIdx[1..nIdx-1]: Keys for other table indexes 
  **   Register aRegIdx[nIdx]:      Data record for table row.
  */
  if( !isView ){
    int nIdx;

    baseCur = pParse->nTab;
    nIdx = sqlite4OpenAllIndexes(pParse, pTab, baseCur, OP_OpenWrite);
    aRegIdx = sqlite4DbMallocRaw(db, sizeof(int)*(nIdx+1));
    if( aRegIdx==0 ){
      goto insert_cleanup;
    }
    for(i=0; i<nIdx; i++){
      aRegIdx[i] = ++pParse->nMem;  /* Register in which to store key */
      pParse->nMem++;               /* Extra register for data */
................................................................................
    **         goto C
    **      D: ...
    */
    addrCont = sqlite4VdbeAddOp1(v, OP_Yield, dest.iParm);
    addrInsTop = sqlite4VdbeAddOp1(v, OP_If, regEof);
  }

  /* Allocate an array of registers in which to assemble the values for the
  ** new row. If the table has an explicit primary key, we need one register
  ** for each table column. If the table uses an implicit primary key, the
  ** nCol+1 registers are required.  */
  if( bImplicitPK ) regRowid = ++pParse->nMem;
  regContent = pParse->nMem+1;
  pParse->nMem += pTab->nCol;

  if( IsVirtual(pTab) ){
    /* TODO: Fix this */
    regContent++;
    regRowid++;
    pParse->nMem++;
  }


  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite4VdbeMakeLabel(v);
  if( tmask & TRIGGER_BEFORE ){
    int regCols = sqlite4GetTempRange(pParse, pTab->nCol+1);

................................................................................
    /* Fire BEFORE or INSTEAD OF triggers */
    sqlite4CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, regCols-pTab->nCol-1, onError, endOfLoop);

    sqlite4ReleaseTempRange(pParse, regCols, pTab->nCol+1);
  }






  if( !isView ){
    /* If this table has an implicit PRIMARY KEY, populate the regRowid
    ** register with the value to use for the new row.  */
    if( bImplicitPK ){
      sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur+iPk, regRowid);
    }

#if 0
    if( IsVirtual(pTab) ){
      /* The row that the VUpdate opcode will delete: none */
      sqlite4VdbeAddOp2(v, OP_Null, 0, regIns);
    }
    if( keyColumn>=0 ){
      if( useTempTable ){
        sqlite4VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
................................................................................
    }else if( IsVirtual(pTab) ){
      sqlite4VdbeAddOp2(v, OP_Null, 0, regRowid);
    }else{
      sqlite4VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
      appendFlag = 1;
    }
    autoIncStep(pParse, regAutoinc, regRowid);
#endif

    /* Push onto the stack, data for all columns of the new entry, beginning
    ** with the first column.
    */
    nHidden = 0;
    for(i=0; i<pTab->nCol; i++){
      int iRegStore = regContent + i;








      if( pColumn==0 ){
        if( IsHiddenColumn(&pTab->aCol[i]) ){
          assert( IsVirtual(pTab) );
          j = -1;
          nHidden++;
        }else{
          j = i - nHidden;
................................................................................
      sqlite4VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
      sqlite4VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
      sqlite4MayAbort(pParse);
    }else
#endif
    {
      int isReplace;    /* Set to true if constraints may cause a replace */
      sqlite4GenerateConstraintChecks(pParse, pTab, baseCur, 
          regContent, aRegIdx, keyColumn>=0, 0, onError, endOfLoop, &isReplace
      );
      sqlite4FkCheck(pParse, pTab, 0, regIns);
      sqlite4CompleteInsertion(pParse, pTab, baseCur, 
          regContent, aRegIdx, 0, appendFlag, isReplace==0
      );
    }
  }

  /* Update the count of rows that are inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0 ){
................................................................................
  }else if( pSelect ){
    sqlite4VdbeAddOp2(v, OP_Goto, 0, addrCont);
    sqlite4VdbeJumpHere(v, addrInsTop);
  }

  if( !IsVirtual(pTab) && !isView ){
    /* Close all tables opened */

    for(idx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
      sqlite4VdbeAddOp1(v, OP_Close, idx+baseCur);
    }
  }

insert_end:
  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
................................................................................
#ifdef pTrigger
 #undef pTrigger
#endif
#ifdef tmask
 #undef tmask
#endif

/*
** Return the name of the iCol'th column in index pIdx.
*/
const char *indexColumnName(Index *pIdx, int iCol){
  int iTbl = pIdx->aiColumn[iCol];
  assert( iTbl>=-1 && iTbl<pIdx->pTable->nCol );
  if( iTbl<0 ){
    assert( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY && pIdx->nColumn==1 );
    return "rowid";
  }
  return pIdx->pTable->aCol[iTbl].zName;
}

static void generateNotNullChecks(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table to generate checks for */
  int regContent,                 /* Index of the range of input registers */
  int overrideError,              /* Override default OE_* with this */
  int ignoreDest                  /* Jump to this lable if OE_Ignore */
){
  Vdbe *v = pParse->pVdbe;
  int i;

  for(i=0; i<pTab->nCol; i++){
    int onError = pTab->aCol[i].notNull;
    if( onError ){
      if( overrideError!=OE_Default ){
        onError = overrideError;
      }else if( onError==OE_Default ){
        onError = OE_Abort;
      }
      if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
        onError = OE_Abort;
      }

      switch( onError ){
        case OE_Abort:
          sqlite4MayAbort(pParse);
        case OE_Rollback:
        case OE_Fail: {
          char *zMsg = sqlite4MPrintf(pParse->db, "%s.%s may not be NULL",
              pTab->zName, pTab->aCol[i].zName
          );
          sqlite4VdbeAddOp4(v, OP_HaltIfNull, 
              SQLITE_CONSTRAINT, onError, regContent+i, zMsg, P4_DYNAMIC
          );
          break;
        }

        case OE_Ignore:
          sqlite4VdbeAddOp2(v, OP_IsNull, regContent+i, ignoreDest);
          break;

        default: {
          int j1 = sqlite4VdbeAddOp1(v, OP_NotNull, regContent+i);
          sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regContent+i);
          sqlite4VdbeJumpHere(v, j1);
          assert( onError==OE_Replace );
          break;
        }
      }
    }
  }
}

#ifndef SQLITE_OMIT_CHECK
static void generateCheckChecks(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table to generate checks for */
  int regContent,                 /* Index of the range of input registers */
  int overrideError,              /* Override default OE_* with this */
  int ignoreDest                  /* Jump to this lable if OE_Ignore */
){
  Vdbe *v = pParse->pVdbe;

  if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
    int onError;
    int allOk = sqlite4VdbeMakeLabel(v);
    pParse->ckBase = regContent;
    sqlite4ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
    if( onError==OE_Ignore ){
      sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
    }else{
      if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
      sqlite4HaltConstraint(pParse, onError, 0, 0);
    }
    sqlite4VdbeResolveLabel(v, allOk);
  }
}
#else /* !defined(SQLITE_OMIT_CHECK) */
# define generateCheckChecks(a,b,c,d,e)
#endif

Index *sqlite4FindPrimaryKey(
  Table *pTab,                    /* Table to locate primary key for */
  int *piPk                       /* OUT: Index of PRIMARY KEY */
){
  Index *p;
  int iPk = 0;
  for(p=pTab->pIndex; p && p->eIndexType!=SQLITE_INDEX_PRIMARYKEY; p=p->pNext){
    iPk++;
  }
  if( piPk ) *piPk = iPk;
  return p;
}

/*
** This function generates code used as part of both INSERT and UPDATE
** statements. The generated code performs two tasks:
**
**   1. Checks all NOT NULL, CHECK and UNIQUE database constraints, 
**      including the implicit NOT NULL and UNIQUE constraints imposed
**      by the PRIMARY KEY definition.
**
**   2. Generates serialized index keys (using OP_MakeKey) for the caller
**      to store in database indexes. This function does not encode the
**      actual data record, just the index keys.
**
** Both INSERT and UPDATE use this function in concert with the
** sqlite4CompleteInsertion(). This function does as described above, and
** then CompleteInsertion() generates code to serialize the data record 
** and do the actual inserts into the database.
**
** regContent:
**   The first in an array of registers that contain the column values
**   for the new row. Register regContent contains the value for the 
**   left-most table column, (regContent+1) contains the value for the next 
**   column, and so on. All entries in this array have had any required
**   affinity transformations applied already. All zero-blobs have been 
**   expanded.
**
**   If the table has an implicit primary key and aRegIdx[0] is not 0 (see
**   below), register (regContent-1) is also valid. It contains the new 
**   implicit integer PRIMARY KEY value.
**
** aRegIdx:
**   Array sized so that there is one entry for each index (including the
**   PK index) attached to the database table. Entries are in the same order
**   as the linked list of Index structures attached to the table. 
**
**   If an array entry is non-zero, it contains the register that the 
**   corresponding index key should be written to. If an entry is zero, then
**   the corresponding index key is not required by the caller and that any 
**   UNIQUE enforced by the index does not need to be checked.
**
** 
**
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
**
** The input is a range of consecutive registers as follows:
**
**    1.  The rowid of the row after the update.
**
**    2.  The data in the first column of the entry after the update.
................................................................................
** read/write cursors with cursor number baseCur+i for the i-th cursor.
** Except, if there is no possibility of a REPLACE action then
** cursors do not need to be open for indices where aRegIdx[i]==0.
*/
void sqlite4GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* First in array of cursors for pTab indexes */
  int regContent,     /* Index of the range of input registers */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */

  int rowidChng,      /* True if the rowid might collide with existing entry */
  int isUpdate,       /* True for UPDATE, False for INSERT */

  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest,     /* Jump to this label on an OE_Ignore resolution */
  int *pbMayReplace   /* OUT: Set to true if constraint may cause a replace */
){
  Index *pPk;                     /* Primary key index for table pTab */
  int i;              /* loop counter */
  Vdbe *v;            /* VDBE under constrution */
  int nCol;           /* Number of columns */
  int onError;        /* Conflict resolution strategy */



  int iCur;           /* Table cursor number */
  Index *pIdx;         /* Pointer to one of the indices */
  int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */


  v = sqlite4GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;

  pPk = sqlite4FindPrimaryKey(pTab, 0);

  assert( pPk->eIndexType==SQLITE_INDEX_PRIMARYKEY );

  /* Test all NOT NULL constraints. */

  generateNotNullChecks(pParse, pTab, regContent, overrideError, ignoreDest);










































  /* Test all CHECK constraints */












  generateCheckChecks(pParse, pTab, regContent, overrideError, ignoreDest);




















































































  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){


    int nTmpReg;                  /* Number of temp registers required */
    int regTmp;                   /* First temp register allocated */
    int regShort;                 /* Reg. for number of bytes in short key */

    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */

    /* Create an index key. Primary key indexes consists of just the primary
    ** key values. Other indexes consists of the indexed columns followed by
    ** the primary key values.  */
    nTmpReg = 1 + pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn);
    regTmp = sqlite4GetTempRange(pParse, nTmpReg);
    regShort = regTmp + nTmpReg - 1;
    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];

      sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i);

    }
    if( pIdx!=pPk ){
      for(i=0; i<pPk->nColumn; i++){
        int idx = pPk->aiColumn[i];
        sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i+pIdx->nColumn);
      }
    }


    sqlite4VdbeAddOp3(v, OP_MakeIdxKey, baseCur+iCur, regTmp, aRegIdx[iCur]);
    sqlite4VdbeChangeP4(v, -1, (const char *)regShort, P4_INT32);

    VdbeComment((v, "key for %s", pIdx->zName));


    /* If Index.onError==OE_None, then pIdx is not a UNIQUE or PRIMARY KEY 
    ** index. In this case there is no need to test the index for uniqueness
    ** - all that is required is to populate the aRegIdx[iCur] register. Jump 
    ** to the next iteration of the loop if this is the case.  */
    onError = pIdx->onError;
    if( onError!=OE_None ){


      int iTest;                  /* Address of OP_IsUnique instruction */

      iTest = sqlite4VdbeAddOp3(v, OP_IsUnique, baseCur+iCur, 0, aRegIdx[iCur]);
      sqlite4VdbeChangeP4(v, -1, (const char *)regShort, P4_INT32);

      /* Figure out what to do if a UNIQUE constraint is encountered. 
      **
      ** TODO: If a previous constraint is a REPLACE, why change IGNORE to
      ** REPLACE and FAIL to ABORT here?  */
      if( overrideError!=OE_Default ){
        onError = overrideError;
      }else if( onError==OE_Default ){
        onError = OE_Abort;
      }
      if( seenReplace ){
        if( onError==OE_Ignore ) onError = OE_Replace;
        else if( onError==OE_Fail ) onError = OE_Abort;
      }
      











      switch( onError ){
        case OE_Rollback:
        case OE_Abort:
        case OE_Fail: {
          int j;
          StrAccum errMsg;
          const char *zSep;
          char *zErr;

          sqlite4StrAccumInit(&errMsg, 0, 0, 200);
          errMsg.db = pParse->db;
          zSep = pIdx->nColumn>1 ? "columns " : "column ";
          for(j=0; j<pIdx->nColumn; j++){

            const char *zCol = indexColumnName(pIdx, j);
            sqlite4StrAccumAppend(&errMsg, zSep, -1);
            zSep = ", ";
            sqlite4StrAccumAppend(&errMsg, zCol, -1);
          }
          sqlite4StrAccumAppend(&errMsg,
              pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
          zErr = sqlite4StrAccumFinish(&errMsg);
          sqlite4HaltConstraint(pParse, onError, zErr, 0);
          sqlite4DbFree(errMsg.db, zErr);
          break;
        }
        case OE_Ignore: {
          assert( seenReplace==0 );
          sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
          break;
        }
        default: {
          assert( 0 );
#if 0
          Trigger *pTrigger = 0;
          assert( onError==OE_Replace );
          sqlite4MultiWrite(pParse);
          if( pParse->db->flags&SQLITE_RecTriggers ){
            pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
          }
          sqlite4GenerateRowDelete(
              pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
          );
          seenReplace = 1;
#endif
          break;
        }
      }

      /* If the OP_IsUnique passes (no constraint violation) jump here */
      sqlite4VdbeJumpHere(v, iTest);
    }

    sqlite4ReleaseTempRange(pParse, regTmp, nTmpReg);
  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite4GenerateConstraintChecks.



** The arguments to this routine should be the same as the first six
** arguments to sqlite4GenerateConstraintChecks.
**
** Argument regContent points to the first in a contiguous array of 
** registers that contain the row content. This function uses OP_MakeRecord
** to encode them into a record before inserting them into the database.
**
** The array aRegIdx[] contains one entry for each index attached to
** the table, in the same order as the Table.pIndex linked list. If an
** aRegIdx[] entry is 0, this indicates that the entry in the corresponding
** index does not need to be modified. Otherwise, it is the number of
** a register containing the serialized key to insert into the index.
** aRegIdx[0] (the PRIMARY KEY index key) is never 0.
*/
void sqlite4CompleteInsertion(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* Index of a read/write cursor pointing at pTab */
  int regContent,     /* First register of content */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int appendBias,     /* True if this is likely to be an append */
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  int i;
  Vdbe *v;

  Index *pIdx;
  u8 pik_flags;

  int regRec;

  v = sqlite4GetVdbe(pParse);
  assert( aRegIdx[0] );
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */













  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE | (isUpdate?OPFLAG_ISUPDATE:0);
  }

  /* Generate code to serialize array of registers into a database record. */
  regRec = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, regContent, pTab->nCol, regRec);
  sqlite4TableAffinityStr(v, pTab);
  sqlite4ExprCacheAffinityChange(pParse, regContent, pTab->nCol);

  /* Write the entry to each index. */
  for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    if( aRegIdx[i] ){
      int regData = 0;
      int flags = 0;
      if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
        regData = regRec;
        flags = pik_flags;
      }
      sqlite4VdbeAddOp3(v, OP_IdxInsert, baseCur+i, regData, aRegIdx[i]);
    }
  }
}

/*
** Generate code that will open cursors for a table and for all
** indices of that table.  The "baseCur" parameter is the cursor number used
** for the table.  Indices are opened on subsequent cursors.
**
** Return the number of indices on the table.
*/
int sqlite4OpenAllIndexes(
  Parse *pParse,   /* Parsing context */
  Table *pTab,     /* Table to be opened */
  int baseCur,     /* Cursor number assigned to the table */
  int op           /* OP_OpenRead or OP_OpenWrite */
){
  int i = 0;
  if( IsVirtual(pTab)==0 ){
    int iDb;
    Index *pIdx;

    iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      sqlite4OpenIndex(pParse, baseCur+i, iDb, pIdx, op);
      i++;
    }
    if( pParse->nTab<baseCur+i ){
      pParse->nTab = baseCur+i;
    }
  }
  return i;
}

void sqlite4CloseAllIndexes(
  Parse *pParse,
  Table *pTab,
  int baseCur
){
  int i;
  Index *pIdx;
  Vdbe *v;

  assert( pTab->pIndex==0 || IsVirtual(pTab)==0 );
#ifndef SQLITE_OMIT_VIEW
  assert( pTab->pIndex==0 || pTab->pSelect==0 );
#endif

  v = sqlite4GetVdbe(pParse);


  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){

    sqlite4VdbeAddOp1(v, OP_Close, baseCur+i);



  }




}


#ifdef SQLITE_TEST
/*
** The following global variable is incremented whenever the
** transfer optimization is used.  This is used for testing

Changes to src/parse.y.

285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
....
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
  sqlite4AddDefaultValue(pParse,&v);
}

// In addition to the type name, we also care about the primary key and
// UNIQUE constraints.
//
ccons ::= NULL onconf.
ccons ::= NOT NULL onconf(R).    {sqlite4AddNotNull(pParse, R);}
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
                                 {sqlite4AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R).      {sqlite4CreateIndex(pParse,0,0,0,0,R,0,0,0,0);}
ccons ::= CHECK LP expr(X) RP.   {sqlite4AddCheckConstraint(pParse,X.pExpr);}
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
                                 {sqlite4CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D).    {sqlite4DeferForeignKey(pParse,D);}
ccons ::= COLLATE ids(C).        {sqlite4AddCollateType(pParse, &C);}

// The optional AUTOINCREMENT keyword
%type autoinc {int}
autoinc(X) ::= .          {X = 0;}
autoinc(X) ::= AUTOINCR.  {X = 1;}

// The next group of rules parses the arguments to a REFERENCES clause
................................................................................
conslist_opt(A) ::= .                   {A.n = 0; A.z = 0;}
conslist_opt(A) ::= COMMA(X) conslist.  {A = X;}
conslist ::= conslist COMMA tcons.
conslist ::= conslist tcons.
conslist ::= tcons.
tcons ::= CONSTRAINT nm.
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
                                 {sqlite4AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
                                 {sqlite4CreateIndex(pParse,0,0,0,X,R,0,0,0,0);}
tcons ::= CHECK LP expr(E) RP onconf.
                                 {sqlite4AddCheckConstraint(pParse,E.pExpr);}
tcons ::= FOREIGN KEY LP idxlist(FA) RP
          REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
    sqlite4CreateForeignKey(pParse, FA, &T, TA, R);
    sqlite4DeferForeignKey(pParse, D);
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= .                    {A = 0;}
................................................................................

///////////////////////////// The CREATE INDEX command ///////////////////////
//
cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
        ON nm(Y) LP idxlist(Z) RP(E). {
  sqlite4CreateIndex(pParse, &X, &D, 
                     sqlite4SrcListAppend(pParse->db,0,&Y,0), Z, U,
                      &S, &E, SQLITE_SO_ASC, NE);
}

%type uniqueflag {int}
uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
uniqueflag(A) ::= .        {A = OE_None;}

%type idxlist {ExprList*}







|

|
|
|

|
|
|







 







|

|

|







 







|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
....
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
  sqlite4AddDefaultValue(pParse,&v);
}

// In addition to the type name, we also care about the primary key and
// UNIQUE constraints.
//
ccons ::= NULL onconf.
ccons ::= NOT NULL onconf(R).  {sqlite4AddNotNull(pParse, R);}
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
                               {sqlite4AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R).    {sqlite4CreateIndex(pParse,0,0,0,0,R,0,0,0,0,0);}
ccons ::= CHECK LP expr(X) RP. {sqlite4AddCheckConstraint(pParse,X.pExpr);}
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
                               {sqlite4CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D).  {sqlite4DeferForeignKey(pParse,D);}
ccons ::= COLLATE ids(C).      {sqlite4AddCollateType(pParse, &C);}

// The optional AUTOINCREMENT keyword
%type autoinc {int}
autoinc(X) ::= .          {X = 0;}
autoinc(X) ::= AUTOINCR.  {X = 1;}

// The next group of rules parses the arguments to a REFERENCES clause
................................................................................
conslist_opt(A) ::= .                   {A.n = 0; A.z = 0;}
conslist_opt(A) ::= COMMA(X) conslist.  {A = X;}
conslist ::= conslist COMMA tcons.
conslist ::= conslist tcons.
conslist ::= tcons.
tcons ::= CONSTRAINT nm.
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
                             {sqlite4AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
                             {sqlite4CreateIndex(pParse,0,0,0,X,R,0,0,0,0,0);}
tcons ::= CHECK LP expr(E) RP onconf.
                             {sqlite4AddCheckConstraint(pParse,E.pExpr);}
tcons ::= FOREIGN KEY LP idxlist(FA) RP
          REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
    sqlite4CreateForeignKey(pParse, FA, &T, TA, R);
    sqlite4DeferForeignKey(pParse, D);
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= .                    {A = 0;}
................................................................................

///////////////////////////// The CREATE INDEX command ///////////////////////
//
cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
        ON nm(Y) LP idxlist(Z) RP(E). {
  sqlite4CreateIndex(pParse, &X, &D, 
                     sqlite4SrcListAppend(pParse->db,0,&Y,0), Z, U,
                      &S, &E, SQLITE_SO_ASC, NE, 0);
}

%type uniqueflag {int}
uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
uniqueflag(A) ::= .        {A = OE_None;}

%type idxlist {ExprList*}

Changes to src/pragma.c.

532
533
534
535
536
537
538





























































































































































539
540
541
542
543
544
545
  **
  ** Print an ascii rendering of the complete content of the database file.
  */
  if( sqlite4StrICmp(zLeft, "kvdump")==0 ){
    sqlite4KVStoreDump(db->aDb[0].pKV);
  }else
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */































































































































































  /*
  **  PRAGMA shrink_memory
  **
  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  **
  ** Print an ascii rendering of the complete content of the database file.
  */
  if( sqlite4StrICmp(zLeft, "kvdump")==0 ){
    sqlite4KVStoreDump(db->aDb[0].pKV);
  }else
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
  /*
  **   PRAGMA integrity_check
  **
  ** Check that for each table, the content of any auxilliary indexes are 
  ** consistent with the primary key index.
  */
  if( sqlite4StrICmp(zLeft, "integrity_check")==0 ){
    const int baseCsr = 1;        /* Base cursor for OpenAllIndexes() call */

    const int regErrcnt = 1;      /* Register containing error count */
    const int regErrstr = 2;      /* Register containing error string */
    const int regTmp = 3;         /* Register for tmp use */
    const int regRowcnt1 = 4;     /* Register containing row count (from PK) */
    const int regRowcnt2 = 5;     /* Register containing error count */
    const int regResult = 6;      /* Register containing result string */
    const int regKey = 7;         /* Register containing encoded key */
    const int regArray = 8;       /* First in array of registers */

    int i;
    int nMaxArray = 1;
    int addrNot = 0;
    Vdbe *v;

    if( sqlite4ReadSchema(pParse) ) goto pragma_out;

    for(i=0; i<db->nDb; i++){
      if( OMIT_TEMPDB && i==1 ) continue;
      sqlite4CodeVerifySchema(pParse, i);
    }

    v = sqlite4GetVdbe(pParse);
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regErrcnt);
    sqlite4VdbeAddOp4(v, OP_String8, 0, regErrstr, 0, "", 0);

    for(i=0; i<db->nDb; i++){
      Hash *pTbls;
      HashElem *x;

      if( OMIT_TEMPDB && i==1 ) continue;

      pTbls = &db->aDb[i].pSchema->tblHash;
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Index *pIdx;
        Table *pTab = (Table *)sqliteHashData(x);
        int addrRewind;
        int nIdx = 0;
        int iPkCsr;
        Index *pPk;
        int iCsr;

        /* Open all indexes for table pTab. */
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
            pPk = pIdx;
            iPkCsr = nIdx+baseCsr;
          }
          nIdx++;
        }
        sqlite4OpenAllIndexes(pParse, pTab, baseCsr, OP_OpenRead);

        sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowcnt1);
        addrRewind = sqlite4VdbeAddOp1(v, OP_Rewind, iPkCsr);

        /* Increment the row-count register */
        sqlite4VdbeAddOp2(v, OP_AddImm, regRowcnt1, 1);

        for(iCsr=baseCsr, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCsr++){
          assert( (pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY)==(iCsr==iPkCsr) );
          if( iCsr!=iPkCsr ){
            char *zErr;
            int iCol;
            int jmp;
            for(iCol=0; iCol<pIdx->nColumn; iCol++){
              int r = regArray + iCol;
              sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pIdx->aiColumn[iCol], r);
              assert( pIdx->aiColumn[iCol]>=0 );
            }
            for(iCol=0; iCol<pPk->nColumn; iCol++){
              int reg = regArray + pIdx->nColumn + iCol;
              int iTblCol = pPk->aiColumn[iCol];
              if( iTblCol<0 ){
                sqlite4VdbeAddOp2(v, OP_Rowid, iPkCsr, reg);
              }else{
                sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, iTblCol, reg);
              }
            }

            if( (pPk->nColumn+pIdx->nColumn)>nMaxArray ){
              nMaxArray = pPk->nColumn + pIdx->nColumn;
            }

            sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iCsr, regArray, regKey);
            jmp = sqlite4VdbeAddOp4(v, OP_Found, iCsr, 0, regKey, 0, P4_INT32);
            sqlite4VdbeAddOp2(v, OP_AddImm, regErrcnt, 1);
            zErr = sqlite4MPrintf(
                db, "entry missing from index %s: ", pIdx->zName
            );
            sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, zErr, 0);
            sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
            sqlite4VdbeAddOp3(v, OP_Function, 0, regKey, regTmp);
            sqlite4VdbeChangeP4(v, -1,
                (char *)sqlite4FindFunction(db, "hex", 3, 1, SQLITE_UTF8, 0), 
                P4_FUNCDEF
            );
            sqlite4VdbeChangeP5(v, 1);
            sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
            sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, "\n", 0);
            sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
            sqlite4VdbeJumpHere(v, jmp);
            sqlite4DbFree(db, zErr);
          }
        }
        sqlite4VdbeAddOp2(v, OP_Next, iPkCsr, addrRewind+1);
        sqlite4VdbeJumpHere(v, addrRewind);

        for(iCsr=baseCsr, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCsr++){
          if( iCsr!=iPkCsr ){
            char *zErr;
            int addrEq;
            int addrRewind2;
            sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowcnt2);
            addrRewind2 = sqlite4VdbeAddOp1(v, OP_Rewind, iCsr);
            sqlite4VdbeAddOp2(v, OP_AddImm, regRowcnt2, 1);
            sqlite4VdbeAddOp2(v, OP_Next, iCsr, addrRewind2+1);
            sqlite4VdbeJumpHere(v, addrRewind2);
            zErr = sqlite4MPrintf(
                db, "wrong # number of entries in index %s\n", pIdx->zName
            );
            addrEq = sqlite4VdbeAddOp3(v, OP_Eq, regRowcnt1, 0, regRowcnt2);
            sqlite4VdbeAddOp2(v, OP_AddImm, regErrcnt, 1);
            sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, zErr, 0);
            sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);

            sqlite4VdbeJumpHere(v, addrEq);
            sqlite4DbFree(db, zErr);
          }
        }

        for(iCsr=baseCsr; iCsr<(baseCsr+nIdx); iCsr++){
          sqlite4VdbeAddOp1(v, OP_Close, iCsr);
        }
      }
    }

    sqlite4VdbeAddOp4(v, OP_String8, 0, regResult, 0, "ok", 0);
    addrNot = sqlite4VdbeAddOp1(v, OP_IfNot, regErrcnt);
    sqlite4VdbeAddOp4(v, OP_String8, 0, regArray, 0, " errors:\n", 0);
    sqlite4VdbeAddOp3(v, OP_Concat, regArray, regErrcnt, regResult);
    sqlite4VdbeAddOp3(v, OP_Concat, regErrstr, regResult, regResult);
    sqlite4VdbeJumpHere(v, addrNot);

    pParse->nMem = (regArray + nMaxArray);
    sqlite4VdbeSetNumCols(v, 1);
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
    sqlite4VdbeAddOp2(v, OP_ResultRow, regResult, 1);

  }else


  /*
  **  PRAGMA shrink_memory
  **
  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.

Changes to src/rowset.c.

416
417
418
419
420
421
422







































































      p = p->pLeft;
    }else{
      return 1;
    }
  }
  return 0;
}














































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
      p = p->pLeft;
    }else{
      return 1;
    }
  }
  return 0;
}

typedef struct KeySetEntry KeySetEntry;

struct KeySetEntry {
  char *z;
  int n;
  KeySetEntry *pNext;
};

struct KeySet {
  sqlite4 *db;                    /* Database handle for sqlite4DbMalloc() */
  KeySetEntry *pFirst;
  KeySetEntry *pLast;
};

KeySet *sqlite4KeySetInit(sqlite4 *db){
  KeySet *pRet;
  pRet = (KeySet *)sqlite4DbMallocZero(db, sizeof(KeySet));
  if( pRet ){
    pRet->db = db;
  }
  return pRet;
}

void sqlite4KeySetInsert(KeySet *pKeySet, const char *z, int n){
  KeySetEntry *pNew;
  int nByte = n + sizeof(KeySetEntry);

  pNew = (KeySetEntry *)sqlite4DbMallocZero(pKeySet->db, nByte);
  if( pNew ){
    pNew->z = (char *)&pNew[1];
    pNew->n =n;
    memcpy(pNew->z, z, n);
    if( pKeySet->pFirst ){
      pKeySet->pLast = pKeySet->pLast->pNext = pNew;
    }else{
      pKeySet->pLast = pKeySet->pFirst = pNew;
    }
  }
}

/*
** Read the blob of data stored in the current key-set entry.
*/
const char *sqlite4KeySetRead(KeySet *pKeySet, int *pn){
  const char *pRet;
  if( pKeySet->pFirst ){
    *pn = pKeySet->pFirst->n;
    pRet = pKeySet->pFirst->z;
  }else{
    pRet = 0;
    *pn = 0;
  }
  return pRet;
}

int sqlite4KeySetNext(KeySet *pKeySet){
  KeySetEntry *pFirst = pKeySet->pFirst->pNext;
  sqlite4DbFree(pKeySet->db, pKeySet->pFirst);
  pKeySet->pFirst = pFirst;
  return (pFirst!=0);
}

void sqlite4KeySetFree(KeySet *pKeySet){
  while( pKeySet->pFirst ){
    sqlite4KeySetNext(pKeySet);
  }
  sqlite4DbFree(pKeySet->db, pKeySet);
}


Changes to src/sqliteInt.h.

650
651
652
653
654
655
656

657
658
659
660
661
662
663
...
673
674
675
676
677
678
679

680
681
682
683
684
685
686
....
1293
1294
1295
1296
1297
1298
1299

1300

1301
1302
1303
1304
1305
1306
1307
....
1428
1429
1430
1431
1432
1433
1434

1435
1436
1437
1438
1439
1440
1441
....
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515





1516
1517
1518
1519
1520
1521
1522
....
2244
2245
2246
2247
2248
2249
2250

2251

2252
2253
2254
2255
2256
2257
2258
....
2749
2750
2751
2752
2753
2754
2755






2756
2757
2758
2759
2760
2761
2762
....
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
....
3079
3080
3081
3082
3083
3084
3085






3086
3087
3088
3089
3090
3091
3092
typedef struct FuncDef FuncDef;
typedef struct FuncDefHash FuncDefHash;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct IndexSample IndexSample;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;

typedef struct Lookaside Lookaside;
typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
................................................................................
typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WherePlan WherePlan;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;


/*
** Defer sourcing vdbe.h until after the "u8" and 
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
#include "vdbe.h"
................................................................................
*/
struct Table {
  char *zName;         /* Name of the table or view */
  int iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
  int nCol;            /* Number of columns in this table */
  Column *aCol;        /* Information about each column */
  Index *pIndex;       /* List of SQL indexes on this table. */

  int tnum;            /* Root BTree node for this table (see note above) */

  tRowcnt nRowEst;     /* Estimated rows in table - from sqlite_stat1 table */
  Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
  u16 nRef;            /* Number of pointers to this Table */
  u8 tabFlags;         /* Mask of TF_* values */
  u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
  FKey *pFKey;         /* Linked list of all foreign keys in this table */
  char *zColAff;       /* String defining the affinity of each column */
................................................................................
** each key, and the number of primary key fields appended to the end.
*/
struct KeyInfo {
  sqlite4 *db;        /* The database connection */
  u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  u16 nField;         /* Total number of entries in aColl[] */
  u16 nPK;            /* Number of primary key entries at the end of aColl[] */

  u8 *aSortOrder;     /* Sort order for each column.  May be NULL */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
................................................................................
  char *zName;     /* Name of this index */
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  u8 bUnordered;   /* Use this index for == or IN queries only */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema; /* Schema containing this index */
  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  char **azColl;   /* Array of collation sequence names for index */
#ifdef SQLITE_ENABLE_STAT3
  int nSample;             /* Number of elements in aSample[] */
  tRowcnt avgEq;           /* Average nEq value for key values not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
#endif
};






/*
** Each sample stored in the sqlite_stat3 table is represented in memory 
** using a structure of this type.  See documentation at the top of the
** analyze.c source file for additional information.
*/
struct IndexSample {
  union {
................................................................................
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */

  int regRoot;         /* Register holding root page number for new objects */

  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  int nMaxArg;         /* Max args passed to user function by sub-program */

  /* Information used while coding trigger programs. */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  u32 oldmask;         /* Mask of old.* columns referenced */
................................................................................
int sqlite4BitvecBuiltinTest(int,int*);

RowSet *sqlite4RowSetInit(sqlite4*, void*, unsigned int);
void sqlite4RowSetClear(RowSet*);
void sqlite4RowSetInsert(RowSet*, i64);
int sqlite4RowSetTest(RowSet*, u8 iBatch, i64);
int sqlite4RowSetNext(RowSet*, i64*);







void sqlite4CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);

#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
  int sqlite4ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite4ViewGetColumnNames(A,B) 0
................................................................................
void sqlite4SrcListIndexedBy(Parse *, SrcList *, Token *);
int sqlite4IndexedByLookup(Parse *, struct SrcList_item *);
void sqlite4SrcListShiftJoinType(SrcList*);
void sqlite4SrcListAssignCursors(Parse*, SrcList*);
void sqlite4IdListDelete(sqlite4*, IdList*);
void sqlite4SrcListDelete(sqlite4*, SrcList*);
Index *sqlite4CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*, int, int);
void sqlite4DropIndex(Parse*, SrcList*, int);
int sqlite4Select(Parse*, Select*, SelectDest*);
Select *sqlite4SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,int,Expr*,Expr*);
void sqlite4SelectDelete(sqlite4*, Select*);
Table *sqlite4SrcListLookup(Parse*, SrcList*);
int sqlite4IsReadOnly(Parse*, Table*, int);
................................................................................
void sqlite4StrAccumInit(StrAccum*, char*, int, int);
void sqlite4StrAccumAppend(StrAccum*,const char*,int);
void sqlite4AppendSpace(StrAccum*,int);
char *sqlite4StrAccumFinish(StrAccum*);
void sqlite4StrAccumReset(StrAccum*);
void sqlite4SelectDestInit(SelectDest*,int,int);
Expr *sqlite4CreateColumnExpr(sqlite4 *, SrcList *, int, int);







/*
** The interface to the LEMON-generated parser
*/
void *sqlite4ParserAlloc(void*(*)(size_t));
void sqlite4ParserFree(void*, void(*)(void*));
void sqlite4Parser(void*, int, Token, Parse*);







>







 







>







 







>

>







 







>







 







|













>
>
>
>
>







 







>

>







 







>
>
>
>
>
>







 







|







 







>
>
>
>
>
>







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
...
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
....
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
....
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
....
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
....
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
....
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
....
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
....
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
typedef struct FuncDef FuncDef;
typedef struct FuncDefHash FuncDefHash;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct IndexSample IndexSample;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct KeySet KeySet;
typedef struct Lookaside Lookaside;
typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
................................................................................
typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WherePlan WherePlan;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;


/*
** Defer sourcing vdbe.h until after the "u8" and 
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
#include "vdbe.h"
................................................................................
*/
struct Table {
  char *zName;         /* Name of the table or view */
  int iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
  int nCol;            /* Number of columns in this table */
  Column *aCol;        /* Information about each column */
  Index *pIndex;       /* List of SQL indexes on this table. */
#if 0
  int tnum;            /* Root BTree node for this table (see note above) */
#endif
  tRowcnt nRowEst;     /* Estimated rows in table - from sqlite_stat1 table */
  Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
  u16 nRef;            /* Number of pointers to this Table */
  u8 tabFlags;         /* Mask of TF_* values */
  u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
  FKey *pFKey;         /* Linked list of all foreign keys in this table */
  char *zColAff;       /* String defining the affinity of each column */
................................................................................
** each key, and the number of primary key fields appended to the end.
*/
struct KeyInfo {
  sqlite4 *db;        /* The database connection */
  u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  u16 nField;         /* Total number of entries in aColl[] */
  u16 nPK;            /* Number of primary key entries at the end of aColl[] */
  u16 nData;          /* Number of columns of data in KV entry value */
  u8 *aSortOrder;     /* Sort order for each column.  May be NULL */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
................................................................................
  char *zName;     /* Name of this index */
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 eIndexType;   /* SQLITE_INDEX_USER, UNIQUE or PRIMARYKEY */
  u8 bUnordered;   /* Use this index for == or IN queries only */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema; /* Schema containing this index */
  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  char **azColl;   /* Array of collation sequence names for index */
#ifdef SQLITE_ENABLE_STAT3
  int nSample;             /* Number of elements in aSample[] */
  tRowcnt avgEq;           /* Average nEq value for key values not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
#endif
};

/* Index.eIndexType must be set to one of the following. */
#define SQLITE_INDEX_USER       0 /* Index created by CREATE INDEX statement */
#define SQLITE_INDEX_UNIQUE     1 /* Index created by UNIQUE constraint */
#define SQLITE_INDEX_PRIMARYKEY 2 /* Index is the tables PRIMARY KEY */

/*
** Each sample stored in the sqlite_stat3 table is represented in memory 
** using a structure of this type.  See documentation at the top of the
** analyze.c source file for additional information.
*/
struct IndexSample {
  union {
................................................................................
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
#if 0
  int regRoot;         /* Register holding root page number for new objects */
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  int nMaxArg;         /* Max args passed to user function by sub-program */

  /* Information used while coding trigger programs. */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  u32 oldmask;         /* Mask of old.* columns referenced */
................................................................................
int sqlite4BitvecBuiltinTest(int,int*);

RowSet *sqlite4RowSetInit(sqlite4*, void*, unsigned int);
void sqlite4RowSetClear(RowSet*);
void sqlite4RowSetInsert(RowSet*, i64);
int sqlite4RowSetTest(RowSet*, u8 iBatch, i64);
int sqlite4RowSetNext(RowSet*, i64*);

KeySet *sqlite4KeySetInit(sqlite4*);
void sqlite4KeySetInsert(KeySet *, const char *, int);
const char *sqlite4KeySetRead(KeySet *, int *);
int sqlite4KeySetNext(KeySet *);
void sqlite4KeySetFree(KeySet *);

void sqlite4CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);

#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
  int sqlite4ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite4ViewGetColumnNames(A,B) 0
................................................................................
void sqlite4SrcListIndexedBy(Parse *, SrcList *, Token *);
int sqlite4IndexedByLookup(Parse *, struct SrcList_item *);
void sqlite4SrcListShiftJoinType(SrcList*);
void sqlite4SrcListAssignCursors(Parse*, SrcList*);
void sqlite4IdListDelete(sqlite4*, IdList*);
void sqlite4SrcListDelete(sqlite4*, SrcList*);
Index *sqlite4CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*, int, int, int);
void sqlite4DropIndex(Parse*, SrcList*, int);
int sqlite4Select(Parse*, Select*, SelectDest*);
Select *sqlite4SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,int,Expr*,Expr*);
void sqlite4SelectDelete(sqlite4*, Select*);
Table *sqlite4SrcListLookup(Parse*, SrcList*);
int sqlite4IsReadOnly(Parse*, Table*, int);
................................................................................
void sqlite4StrAccumInit(StrAccum*, char*, int, int);
void sqlite4StrAccumAppend(StrAccum*,const char*,int);
void sqlite4AppendSpace(StrAccum*,int);
char *sqlite4StrAccumFinish(StrAccum*);
void sqlite4StrAccumReset(StrAccum*);
void sqlite4SelectDestInit(SelectDest*,int,int);
Expr *sqlite4CreateColumnExpr(sqlite4 *, SrcList *, int, int);

void sqlite4OpenPrimaryKey(Parse*, int iCur, int iDb, Table*, int);
void sqlite4OpenIndex(Parse*, int iCur, int iDb, Index*, int);
int sqlite4OpenAllIndexes(Parse *, Table *, int, int);
void sqlite4CloseAllIndexes(Parse *, Table *, int);
Index *sqlite4FindPrimaryKey(Table *, int *);

/*
** The interface to the LEMON-generated parser
*/
void *sqlite4ParserAlloc(void*(*)(size_t));
void sqlite4ParserFree(void*, void(*)(void*));
void sqlite4Parser(void*, int, Token, Parse*);

Changes to src/update.c.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
119
120
121
122
123
124
125


126
127
128
129
130
131






132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194


195



196
197
198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218





219
220
221
222
223
224
225
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
























279
280
281
282
283
284
285
286
287
288
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370













371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
...
476
477
478
479
480
481
482
483

484


485
486



487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
...
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
}

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
**          \_______/ \________/     \______/       \________________/
*            onError   pTabList      pChanges             pWhere
*/
void sqlite4Update(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table in which we should change things */
  ExprList *pChanges,    /* Things to be changed */
  Expr *pWhere,          /* The WHERE clause.  May be null */
  int onError            /* How to handle constraint errors */
){
  int i, j;              /* Loop counters */
  Table *pTab;           /* The table to be updated */
  int addr = 0;          /* VDBE instruction address of the start of the loop */
................................................................................
  sqlite4 *db;           /* The database structure */
  int *aRegIdx = 0;      /* One register assigned to each index to be updated */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRowid;         /* True if the record number is being changed */
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */
  int okOnePass;         /* True for one-pass algorithm without the FIFO */
  int hasFK;             /* True if foreign key processing is required */

#ifndef SQLITE_OMIT_TRIGGER
................................................................................
  int isView;            /* True when updating a view (INSTEAD OF trigger) */
  Trigger *pTrigger;     /* List of triggers on pTab, if required */
  int tmask;             /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
#endif
  int newmask;           /* Mask of NEW.* columns accessed by BEFORE triggers */

  /* Register Allocations */


  int regRowCount = 0;   /* A count of rows changed */
  int regOldRowid;       /* The old rowid */
  int regNewRowid;       /* The new rowid */
  int regNew;            /* Content of the NEW.* table in triggers */
  int regOld = 0;        /* Content of OLD.* table in triggers */
  int regRowSet = 0;     /* Rowset of rows to be updated */







  memset(&sContext, 0, sizeof(sContext));
  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    goto update_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite4SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;
  iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);


  /* Figure out if we have any triggers and if the table being
  ** updated is a view.
  */
#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask);
  isView = pTab->pSelect!=0;
................................................................................
  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;

  /* Allocate a cursors for the main database table and for all indices.
  ** The index cursors might not be used, but if they are used they
  ** need to occur right after the database cursor.  So go ahead and
  ** allocate enough space, just in case.
  */
  pTabList->a[0].iCursor = iCur = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }

  /* Initialize the name-context */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;

  /* Resolve the column names in all the expressions of the
  ** of the UPDATE statement.  Also find the column index
  ** for each column to be updated in the pChanges array.  For each
  ** column to be updated, make sure we have authorization to change
  ** that column.
  */

  chngRowid = 0;


  for(i=0; i<pChanges->nExpr; i++){



    if( sqlite4ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
      goto update_cleanup;
    }


    for(j=0; j<pTab->nCol; j++){
      if( sqlite4StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
        if( j==pTab->iPKey ){
          chngRowid = 1;
          pRowidExpr = pChanges->a[i].pExpr;
        }
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){
      if( sqlite4IsRowid(pChanges->a[i].zName) ){
        chngRowid = 1;
        pRowidExpr = pChanges->a[i].pExpr;
      }else{
        sqlite4ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
        pParse->checkSchema = 1;
        goto update_cleanup;
      }

    }





#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqlite4AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName, db->aDb[iDb].zName);
      if( rc==SQLITE_DENY ){
        goto update_cleanup;
................................................................................
      }else if( rc==SQLITE_IGNORE ){
        aXRef[j] = -1;
      }
    }
#endif
  }

  hasFK = sqlite4FkRequired(pParse, pTab, aXRef, chngRowid);

  /* Allocate memory for the array aRegIdx[].  There is one entry in the
  ** array for each index associated with table being updated.  Fill in
  ** the value with a register number for indices that are to be used
  ** and with zero for unused indices.
  */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  if( nIdx>0 ){
    aRegIdx = sqlite4DbMallocRaw(db, sizeof(Index*) * nIdx );
    if( aRegIdx==0 ) goto update_cleanup;
  }
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    int reg;
    if( hasFK || chngRowid ){
      reg = ++pParse->nMem;  /* Register for index key */
      pParse->nMem++;        /* Extra register for index data */
    }else{
      reg = 0;
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ){
          reg = ++pParse->nMem;
          break;
        }
      }
    }
    aRegIdx[j] = reg;
  }

  /* Begin generating code. */
  v = sqlite4GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
  sqlite4BeginWriteOperation(pParse, 1, iDb);

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Virtual tables must be handled separately */
  if( IsVirtual(pTab) ){
    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
                       pWhere, onError);
    pWhere = 0;
    pTabList = 0;
    goto update_cleanup;
  }
#endif

























  /* Allocate required registers. */
  regRowSet = ++pParse->nMem;
  regOldRowid = regNewRowid = ++pParse->nMem;
  if( pTrigger || hasFK ){
    regOld = pParse->nMem + 1;
    pParse->nMem += pTab->nCol;
  }
  if( chngRowid || pTrigger || hasFK ){
    regNewRowid = ++pParse->nMem;
  }
................................................................................
  /* Resolve the column names in all the expressions in the
  ** WHERE clause.
  */
  if( sqlite4ResolveExprNames(&sNC, pWhere) ){
    goto update_cleanup;
  }

  /* Begin the database scan
  */
  sqlite4VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
  pWInfo = sqlite4WhereBegin(
      pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED
  );
  if( pWInfo==0 ) goto update_cleanup;
  okOnePass = pWInfo->okOnePass;

  /* Remember the rowid of every item to be updated.
  */
  sqlite4VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
  if( !okOnePass ){
    sqlite4VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
  }

  /* End the database scan loop.
  */
  sqlite4WhereEnd(pWInfo);

  /* Initialize the count of updated rows
  */
  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
    regRowCount = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  if( !isView ){
    /* 
    ** Open every index that needs updating.  Note that if any
    ** index could potentially invoke a REPLACE conflict resolution 
    ** action, then we need to open all indices because we might need
    ** to be deleting some records.
    */
    if( !okOnePass ) sqlite4OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 
    if( onError==OE_Replace ){
      openAll = 1;
    }else{
      openAll = 0;
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        if( pIdx->onError==OE_Replace ){
          openAll = 1;
          break;
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      assert( aRegIdx );
      if( openAll || aRegIdx[i]>0 ){
        KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIdx);
        sqlite4VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
                       (char*)pKey, P4_KEYINFO_HANDOFF);
        assert( pParse->nTab>iCur+i+1 );
      }
    }
  }

  /* Top of the update loop */













  if( okOnePass ){
    int a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regOldRowid);
    addr = sqlite4VdbeAddOp0(v, OP_Goto);
    sqlite4VdbeJumpHere(v, a1);
  }else{
    addr = sqlite4VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
  }

  /* Make cursor iCur point to the record that is being updated. If
  ** this record does not exist for some reason (deleted by a trigger,
  ** for example, then jump to the next iteration of the RowSet loop.  */
  sqlite4VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);

  /* If the record number will change, set register regNewRowid to
  ** contain the new value. If the record number is not being modified,
  ** then regNewRowid is the same register as regOldRowid, which is
  ** already populated.  */
  assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid );
  if( chngRowid ){
    sqlite4ExprCode(pParse, pRowidExpr, regNewRowid);
    sqlite4VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
  }


  /* If there are triggers on this table, populate an array of registers 
  ** with the required old.* column data.  */
  if( hasFK || pTrigger ){
    u32 oldmask = (hasFK ? sqlite4FkOldmask(pParse, pTab) : 0);
    oldmask |= sqlite4TriggerColmask(pParse, 
        pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
................................................................................
      if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
        sqlite4ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i);
      }else{
        sqlite4VdbeAddOp2(v, OP_Null, 0, regOld+i);
      }
    }
    if( chngRowid==0 ){
      sqlite4VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
    }
  }

  /* Populate the array of registers beginning at regNew with the new
  ** row data. This array is used to check constaints, create the new
  ** table and index records, and as the values for any new.* references
  ** made by triggers.
................................................................................
  ** be used eliminates some redundant opcodes.
  */
  newmask = sqlite4TriggerColmask(
      pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
  );
  sqlite4VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
  for(i=0; i<pTab->nCol; i++){
    if( i==pTab->iPKey ){
      /*sqlite4VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
    }else{
      j = aXRef[i];
      if( j>=0 ){
        sqlite4ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
      }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
        /* This branch loads the value of a column that will not be changed 
        ** into a register. This is done if there are no BEFORE triggers, or
        ** if there are one or more BEFORE triggers that use this value via
        ** a new.* reference in a trigger program.
        */
        testcase( i==31 );
        testcase( i==32 );
        sqlite4VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
        sqlite4ColumnDefault(v, pTab, i, regNew+i);
      }
    }
  }

  /* Fire any BEFORE UPDATE triggers. This happens before constraints are
  ** verified. One could argue that this is wrong.
  */
  if( tmask&TRIGGER_BEFORE ){
    sqlite4VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
    sqlite4TableAffinityStr(v, pTab);
    sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
        TRIGGER_BEFORE, pTab, regOldRowid, onError, addr);

    /* The row-trigger may have deleted the row being updated. In this
    ** case, jump to the next row. No updates or AFTER triggers are 
    ** required. This behaviour - what happens when the row being updated
    ** is deleted or renamed by a BEFORE trigger - is left undefined in the
    ** documentation.
    */
    sqlite4VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);

    /* If it did not delete it, the row-trigger may still have modified 
    ** some of the columns of the row being updated. Load the values for 
    ** all columns not modified by the update statement into their 
    ** registers in case this has happened.
    */
    for(i=0; i<pTab->nCol; i++){
................................................................................
        sqlite4ColumnDefault(v, pTab, i, regNew+i);
      }
    }
  }

  if( !isView ){
    int j1;                       /* Address of jump instruction */


    /* Do constraint checks. */


    sqlite4GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
        aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);




    /* Do FK constraint checks. */
    if( hasFK ){
      sqlite4FkCheck(pParse, pTab, regOldRowid, 0);
    }

    /* Delete the index entries associated with the current record.  */
    j1 = sqlite4VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
    sqlite4GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
  
    /* If changing the record number, delete the old record.  */
    if( hasFK || chngRowid ){
      sqlite4VdbeAddOp2(v, OP_Delete, iCur, 0);
    }
    sqlite4VdbeJumpHere(v, j1);

    if( hasFK ){
      sqlite4FkCheck(pParse, pTab, 0, regNewRowid);
    }
  
    /* Insert the new index entries and the new record. */
    sqlite4CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);

    /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
    ** handle rows (possibly in other tables) that refer via a foreign key
    ** to the row just updated. */ 
    if( hasFK ){
      sqlite4FkActions(pParse, pTab, pChanges, regOldRowid);
    }
  }

  /* Increment the row counter 
  */
  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
    sqlite4VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
  }

  sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
      TRIGGER_AFTER, pTab, regOldRowid, onError, addr);

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqlite4VdbeAddOp2(v, OP_Goto, 0, addr);
  sqlite4VdbeJumpHere(v, addr);

  /* Close all tables */
  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    assert( aRegIdx );
    if( openAll || aRegIdx[i]>0 ){
      sqlite4VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
    }
  }
  sqlite4VdbeAddOp2(v, OP_Close, iCur, 0);

  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
................................................................................
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
  }

update_cleanup:
  sqlite4AuthContextPop(&sContext);
  sqlite4DbFree(db, aRegIdx);
  sqlite4DbFree(db, aXRef);
  sqlite4SrcListDelete(db, pTabList);
  sqlite4ExprListDelete(db, pChanges);
  sqlite4ExprDelete(db, pWhere);
  return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation).  */







|



|







 







<







 







>
>

<



<
>
>
>
>
>
>






|

|
<
|


>







 







|







|

|
|
|
|
<
|
>
|
>
>

>
>
>



>
>

|
<
<
<
|
<
<
<
<
|
<
<
<
<
|
|
|
|
>
|
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|


|




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







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<




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

|



|




|
|
<
<
<
<
<
<
<
<
<
<
>







 







|







 







<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
<










|







|







 








>

>
>
|
<
>
>
>



|



|


|










|





|










|










|







 







|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
104
105
106
107
108
109
110

111
112
113
114
115
116
117
...
118
119
120
121
122
123
124
125
126
127

128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212



213




214




215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
233
234
235
236
237
238
239





























240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358








359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388










389
390
391
392
393
394
395
396
...
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
...
421
422
423
424
425
426
427



428
429
430
431
432
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
...
469
470
471
472
473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
}

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
**          \_______/ \________/     \______/       \________________/
*            onError   pSrc          pChanges             pWhere
*/
void sqlite4Update(
  Parse *pParse,         /* The parser context */
  SrcList *pSrc,         /* The table in which we should change things */
  ExprList *pChanges,    /* Things to be changed */
  Expr *pWhere,          /* The WHERE clause.  May be null */
  int onError            /* How to handle constraint errors */
){
  int i, j;              /* Loop counters */
  Table *pTab;           /* The table to be updated */
  int addr = 0;          /* VDBE instruction address of the start of the loop */
................................................................................
  sqlite4 *db;           /* The database structure */
  int *aRegIdx = 0;      /* One register assigned to each index to be updated */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRowid;         /* True if the record number is being changed */
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */

  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */
  int okOnePass;         /* True for one-pass algorithm without the FIFO */
  int hasFK;             /* True if foreign key processing is required */

#ifndef SQLITE_OMIT_TRIGGER
................................................................................
  int isView;            /* True when updating a view (INSTEAD OF trigger) */
  Trigger *pTrigger;     /* List of triggers on pTab, if required */
  int tmask;             /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
#endif
  int newmask;           /* Mask of NEW.* columns accessed by BEFORE triggers */

  /* Register Allocations */
  int regOldKey;                  /* Register containing the original PK */

  int regRowCount = 0;   /* A count of rows changed */

  int regNewRowid;       /* The new rowid */
  int regNew;            /* Content of the NEW.* table in triggers */
  int regOld = 0;        /* Content of OLD.* table in triggers */


  int regKeySet = 0;              /* Register containing KeySet object */
  Index *pPk;                     /* The primary key index of this table */
  int iPk;                        /* Offset of primary key in aRegIdx[] */
  int bChngPk = 0;                /* True if any PK columns are updated */
  int bOpenAll = 0;               /* True if all indexes were opened */

  memset(&sContext, 0, sizeof(sContext));
  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    goto update_cleanup;
  }
  assert( pSrc->nSrc==1 );

  /* Locate the table which we want to update. */

  pTab = sqlite4SrcListLookup(pParse, pSrc);
  if( pTab==0 ) goto update_cleanup;
  iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
  pPk = sqlite4FindPrimaryKey(pTab, &iPk);

  /* Figure out if we have any triggers and if the table being
  ** updated is a view.
  */
#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask);
  isView = pTab->pSelect!=0;
................................................................................
  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;

  /* Allocate a cursors for the main database table and for all indices.
  ** The index cursors might not be used, but if they are used they
  ** need to occur right after the database cursor.  So go ahead and
  ** allocate enough space, just in case.
  */
  pSrc->a[0].iCursor = iCur = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }

  /* Initialize the name-context */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pSrc;

  /* Resolve the column names in all the expressions of the of the UPDATE 
  ** statement. Also find the column index for each column to be updated in 
  ** the pChanges array.  For each column to be updated, make sure we have
  ** authorization to change that column.  

  **
  ** Also, if any columns that are part of the tables primary key are
  ** to be modified, set the bChngPk variable to true. This is significant
  ** because if the primary key changes, *all* index entries need to be
  ** replaced (not just those that index modified columns).  */
  for(i=0; i<pChanges->nExpr; i++){
    int iPkCol;                      /* To iterate through PK columns */

    /* Resolve any names in the expression for this assignment */
    if( sqlite4ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
      goto update_cleanup;
    }

    /* Resolve the column name on the left of the assignment */
    for(j=0; j<pTab->nCol; j++){
      if( sqlite4StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ) break;



    }




    if( j==pTab->nCol ){




      sqlite4ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
      pParse->checkSchema = 1;
      goto update_cleanup;
    }
    aXRef[j] = i;

    /* Check if this column is part of the primary key. If so, set bChngPk. */
    for(iPkCol=0; iPkCol<pPk->nColumn; iPkCol++){
      if( pPk->aiColumn[iPkCol]==j ) bChngPk = 1;
    }

#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqlite4AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName, db->aDb[iDb].zName);
      if( rc==SQLITE_DENY ){
        goto update_cleanup;
................................................................................
      }else if( rc==SQLITE_IGNORE ){
        aXRef[j] = -1;
      }
    }
#endif
  }






























  /* Begin generating code. */
  v = sqlite4GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
  sqlite4BeginWriteOperation(pParse, 1, iDb);

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Virtual tables must be handled separately */
  if( IsVirtual(pTab) ){
    updateVirtualTable(pParse, pSrc, pTab, pChanges, pRowidExpr, aXRef,
                       pWhere, onError);
    pWhere = 0;
    pSrc = 0;
    goto update_cleanup;
  }
#endif

  hasFK = sqlite4FkRequired(pParse, pTab, aXRef, chngRowid);

  /* Allocate memory for the array aRegIdx[].  There is one entry in the
  ** array for each index associated with table being updated.  Fill in
  ** the value with a register number for indices that are to be used
  ** and with zero for unused indices.  */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  aRegIdx = sqlite4DbMallocZero(db, sizeof(Index*) * nIdx );
  if( aRegIdx==0 ) goto update_cleanup;

  /* Allocate registers for and populate the aRegIdx array. */
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    if( pIdx==pPk || hasFK || bChngPk ){
      aRegIdx[j] = ++pParse->nMem;
    }else{
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ){
          aRegIdx[j] = ++pParse->nMem;
          break;
        }
      }
    }
  }

  /* Allocate other required registers. */
  regKeySet = ++pParse->nMem;
  regOldKey = ++pParse->nMem;
  if( pTrigger || hasFK ){
    regOld = pParse->nMem + 1;
    pParse->nMem += pTab->nCol;
  }
  if( chngRowid || pTrigger || hasFK ){
    regNewRowid = ++pParse->nMem;
  }
................................................................................
  /* Resolve the column names in all the expressions in the
  ** WHERE clause.
  */
  if( sqlite4ResolveExprNames(&sNC, pWhere) ){
    goto update_cleanup;
  }

  /* This block codes a loop that iterates through all rows of the table
  ** identified by the UPDATE statements WHERE clause. The primary key
  ** of each row visited by the loop is added to the KeySet object stored
  ** in register regKeySet.
  **
  ** There is one exception to the above: If static analysis of the WHERE 
  ** clause indicates that the loop will visit at most one row, then the
  ** KeySet object is bypassed and the primary key of the single row (if
  ** any) left in register regOldKey. This is called the "one-pass"
  ** approach. Set okOnePass to true if it can be used in this case.  */
  sqlite4VdbeAddOp3(v, OP_Null, 0, regKeySet, regOldKey);
  pWInfo = sqlite4WhereBegin(pParse, pSrc, pWhere, 0, 0, WHERE_ONEPASS_DESIRED);
  if( pWInfo==0 ) goto update_cleanup;
  okOnePass = pWInfo->okOnePass;
  sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regOldKey);
  if( !okOnePass ){
    sqlite4VdbeAddOp2(v, OP_KeySetAdd, regKeySet, regOldKey);
  }
  sqlite4WhereEnd(pWInfo);

  /* Initialize the count of updated rows */

  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
    regRowCount = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  /* Open every index that needs updating. If any index could potentially 
  ** invoke a REPLACE conflict resolution action, then we need to open all 
  ** indices because we might need to be deleting some records.  */
  if( !isView ){
    /* Set bOpenAll to true if this UPDATE might strike a REPLACE */
    bOpenAll = (onError==OE_Replace);
    for(i=0, pIdx=pTab->pIndex->pNext; pIdx; pIdx=pIdx->pNext, i++){
      if( aRegIdx[i] && pIdx->onError==OE_Replace ) bOpenAll = 1;
    }

    /* If bOpenAll is true, open all indexes. Otherwise, just open those
    ** indexes for which the corresponding aRegIdx[] entry is non-zero
    ** (those that index columns that will be modified by this UPDATE
    ** statement). Also, if the one-pass approach is being used, do not
    ** open the primary key index here - it is already open.  */
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( (bOpenAll || aRegIdx[i]) && (okOnePass==0 || pIdx!=pPk) ){
        sqlite4OpenIndex(pParse, iCur+i, iDb, pIdx, OP_OpenWrite);








      }
    }
  }

  /* The next instruction coded is the top of the update loop (executed once
  ** for each row to be updated). 
  **
  ** If okOnePass is true, then regOldKey either contains the encoded PK of 
  ** the row to update, or it is NULL (indicating that this statement will 
  ** update zero rows). If this is the case, jump to the end of the loop 
  ** without doing anything. Otherwise - if okOnePass is true and regOldKey 
  ** contains something other than NULL - proceed.
  **
  ** Or, if okOnePass is false, then the KeySet object stored in register
  ** regKeySet contains the set of encoded PKs for the rows that will
  ** be updated by this statement. Read the next one into register regOldKey.
  ** Or, if the KeySet is already empty, jump to the end of the loop.
  */
  if( okOnePass ){
    int a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regOldKey);
    addr = sqlite4VdbeAddOp0(v, OP_Goto);
    sqlite4VdbeJumpHere(v, a1);
  }else{
    addr = sqlite4VdbeAddOp3(v, OP_KeySetRead, regKeySet, 0, regOldKey);
  }

  /* Make cursor iCur point to the record that is being updated. If
  ** this record does not exist for some reason (deleted by a trigger,
  ** for example, then jump to the next iteration of the KeySet loop. 
  ** TODO: If okOnePass is true, does iCur already point to this record? */










  sqlite4VdbeAddOp4(v, OP_NotFound, iCur+iPk, addr, regOldKey, 0, P4_INT32);

  /* If there are triggers on this table, populate an array of registers 
  ** with the required old.* column data.  */
  if( hasFK || pTrigger ){
    u32 oldmask = (hasFK ? sqlite4FkOldmask(pParse, pTab) : 0);
    oldmask |= sqlite4TriggerColmask(pParse, 
        pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
................................................................................
      if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
        sqlite4ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i);
      }else{
        sqlite4VdbeAddOp2(v, OP_Null, 0, regOld+i);
      }
    }
    if( chngRowid==0 ){
      sqlite4VdbeAddOp2(v, OP_Copy, regOldKey, regNewRowid);
    }
  }

  /* Populate the array of registers beginning at regNew with the new
  ** row data. This array is used to check constaints, create the new
  ** table and index records, and as the values for any new.* references
  ** made by triggers.
................................................................................
  ** be used eliminates some redundant opcodes.
  */
  newmask = sqlite4TriggerColmask(
      pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
  );
  sqlite4VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
  for(i=0; i<pTab->nCol; i++){



    j = aXRef[i];
    if( j>=0 ){
      sqlite4ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
    }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
      /* This branch loads the value of a column that will not be changed 
       ** into a register. This is done if there are no BEFORE triggers, or
       ** if there are one or more BEFORE triggers that use this value via
       ** a new.* reference in a trigger program.
       */
      testcase( i==31 );
      testcase( i==32 );
      sqlite4VdbeAddOp3(v, OP_Column, iCur+iPk, i, regNew+i);
      sqlite4ColumnDefault(v, pTab, i, regNew+i);

    }
  }

  /* Fire any BEFORE UPDATE triggers. This happens before constraints are
  ** verified. One could argue that this is wrong.
  */
  if( tmask&TRIGGER_BEFORE ){
    sqlite4VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
    sqlite4TableAffinityStr(v, pTab);
    sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
        TRIGGER_BEFORE, pTab, regOldKey, onError, addr);

    /* The row-trigger may have deleted the row being updated. In this
    ** case, jump to the next row. No updates or AFTER triggers are 
    ** required. This behaviour - what happens when the row being updated
    ** is deleted or renamed by a BEFORE trigger - is left undefined in the
    ** documentation.
    */
    sqlite4VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldKey);

    /* If it did not delete it, the row-trigger may still have modified 
    ** some of the columns of the row being updated. Load the values for 
    ** all columns not modified by the update statement into their 
    ** registers in case this has happened.
    */
    for(i=0; i<pTab->nCol; i++){
................................................................................
        sqlite4ColumnDefault(v, pTab, i, regNew+i);
      }
    }
  }

  if( !isView ){
    int j1;                       /* Address of jump instruction */


    /* Do constraint checks. */
    assert( bChngPk==0 || pPk->aiColumn[0]>=0 );
    if( bChngPk==0 ) aRegIdx[iPk] = 0;
    sqlite4GenerateConstraintChecks(

        pParse, pTab, iCur, regNew, aRegIdx, 0, 1, onError, addr, 0
    );
    if( bChngPk==0 ) aRegIdx[iPk] = regOldKey;

    /* Do FK constraint checks. */
    if( hasFK ){
      sqlite4FkCheck(pParse, pTab, regOldKey, 0);
    }

    /* Delete the index entries associated with the current record.  */
    j1 = sqlite4VdbeAddOp4(v, OP_NotFound, iCur+iPk, 0, regOldKey, 0, P4_INT32);
    sqlite4GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
  
    /* Delete the old record */
    if( hasFK || chngRowid ){
      sqlite4VdbeAddOp2(v, OP_Delete, iCur, 0);
    }
    sqlite4VdbeJumpHere(v, j1);

    if( hasFK ){
      sqlite4FkCheck(pParse, pTab, 0, regNewRowid);
    }
  
    /* Insert the new index entries and the new record. */
    sqlite4CompleteInsertion(pParse, pTab, iCur, regNew, aRegIdx, 1, 0, 0);

    /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
    ** handle rows (possibly in other tables) that refer via a foreign key
    ** to the row just updated. */ 
    if( hasFK ){
      sqlite4FkActions(pParse, pTab, pChanges, regOldKey);
    }
  }

  /* Increment the row counter 
  */
  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
    sqlite4VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
  }

  sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
      TRIGGER_AFTER, pTab, regOldKey, onError, addr);

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqlite4VdbeAddOp2(v, OP_Goto, 0, addr);
  sqlite4VdbeJumpHere(v, addr);

  /* Close all tables */
  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    assert( aRegIdx );
    if( bOpenAll || aRegIdx[i] ){
      sqlite4VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
    }
  }
  sqlite4VdbeAddOp2(v, OP_Close, iCur, 0);

  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
................................................................................
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
  }

update_cleanup:
  sqlite4AuthContextPop(&sContext);
  sqlite4DbFree(db, aRegIdx);
  sqlite4DbFree(db, aXRef);
  sqlite4SrcListDelete(db, pSrc);
  sqlite4ExprListDelete(db, pChanges);
  sqlite4ExprDelete(db, pWhere);
  return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation).  */

Changes to src/vdbe.c.

2122
2123
2124
2125
2126
2127
2128


2129
2130
2131
2132

2133
2134
2135
2136
2137
2138
2139
....
2160
2161
2162
2163
2164
2165
2166





















































2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181


2182
2183
2184




2185
2186

2187
2188
2189
2190
2191
2192
2193
....
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
....
2249
2250
2251
2252
2253
2254
2255
2256
2257



2258
2259
2260
2261
2262
2263
2264
....
2602
2603
2604
2605
2606
2607
2608
2609







2610
2611

2612
2613
2614
2615
2616
2617
2618
....
2754
2755
2756
2757
2758
2759
2760

2761
2762
2763
2764
2765
2766
2767
....
2898
2899
2900
2901
2902
2903
2904


2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940























2941
2942
2943
2944
2945
2946
2947
....
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
....
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
....
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
....
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
....
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
....
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633




3634
3635
3636

3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
....
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696








3697











3698
3699
3700
3701
3702
3703
3704
....
3858
3859
3860
3861
3862
3863
3864











































3865
3866
3867
3868
3869
3870
3871
    aData = (const KVByteArray*)pReg->z;
    nData = pReg->n;
  }else{
    aData = 0;
    MemSetTypeFlag(pDest, MEM_Null);
  }
  if( rc==SQLITE_OK && aData ){


    rc = sqlite4VdbeCreateDecoder(db, aData, nData, pC->nField, &pCodec);
    if( rc==0 ){
      pDefault = (pOp->p4type==P4_MEM) ? pOp->p4.pMem : 0;
      rc = sqlite4VdbeDecodeValue(pCodec, pOp->p2, pDefault, pDest);

      sqlite4VdbeDestroyDecoder(pCodec);
    }
  }else{
    sqlite4VdbeMemSetNull(pDest);
  }
  UPDATE_MAX_BLOBSIZE(pDest);
  REGISTER_TRACE(pOp->p3, pDest);
................................................................................
    assert( pIn1 <= &p->aMem[p->nMem] );
    assert( memIsValid(pIn1) );
    applyAffinity(pIn1, cAff, encoding);
    pIn1++;
  }
  break;
}






















































/* Opcode: MakeKey P1 P2 * * *
**
** This must be followed immediately by a MakeRecord opcode.  This
** opcode performs the subsequent MakeRecord and also generates
** a key for the cursor P1 and stores that key in register P2.
*/
/* Opcode: MakeRecord P1 P2 P3 P4 *
**
** Convert registers P1..P1+P2-1 into a data record and store the result
** in register P3.  The OP_Column opcode can be used to decode the record.
**
** P4 may be a string that is P2 characters long.  The nth character of the
** string indicates the column affinity that should be used for the nth
** field of the index key.


**
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.




**
** If P4 is NULL then all index fields have the affinity NONE.

*/
case OP_MakeKey:
case OP_MakeRecord: {
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  Mem *pMem;             /* For looping over inputs */
  int nField;            /* Number of fields in the record */
................................................................................
  nField = pOp->p1;
  zAffinity = pOp->p4.z;
  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
  pData0 = &aMem[nField];
  nField = pOp->p2;
  pLast = &pData0[nField-1];

  /* Identify the output register */
  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
  pOut = &aMem[pOp->p3];
  memAboutToChange(p, pOut);

  /* Loop through the input elements.  Apply affinity to each one and
  ** expand all zero-blobs.
  */
  for(pMem=pData0; pMem<=pLast; pMem++){
    assert( memIsValid(pMem) );
    if( zAffinity ){
      applyAffinity(pMem, *(zAffinity++), encoding);
................................................................................
    }else{
      rc = sqlite4VdbeMemSetStr(pKeyOut, aRec, nRec, 0, SQLITE_DYNAMIC);
      REGISTER_TRACE(keyReg, pKeyOut);
      UPDATE_MAX_BLOBSIZE(pKeyOut);
    }
  }

  /* Compute the value */
  if( rc==SQLITE_OK ){



    aRec = 0;
    rc = sqlite4VdbeEncodeData(db, pData0, nField, &aRec, &nRec);
    if( rc ){
      sqlite4DbFree(db, aRec);
    }else{
      rc = sqlite4VdbeMemSetStr(pOut, aRec, nRec, 0, SQLITE_DYNAMIC);
      REGISTER_TRACE(pOp->p3, pOut);
................................................................................
  VdbeCursor *pCx;

  assert( pOp->p1>=0 );
  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  rc = sqlite4KVStoreOpen(db, "ephm", ":memory:", &pCx->pTmpKV,
          SQLITE_KVOPEN_TEMPORARY | SQLITE_KVOPEN_NO_TRANSACTIONS);







  pCx->pKeyInfo = pOp->p4.pKeyInfo;
  if( pCx->pKeyInfo ) pCx->pKeyInfo->enc = ENC(p->db);

  pCx->isIndex = !pCx->isTable;
  break;
}

/* Opcode: OpenSorter P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
................................................................................
  oc = pOp->opcode;
  pC->nullRow = 0;
  if( pC->isTable ){
    nField = 1;
  }else{
    nField = pOp->p4.i;
  }

  rc = sqlite4VdbeEncodeKey(db, pIn3, nField, pC->iRoot, pC->pKeyInfo,
                            &aProbe, &nProbe, 0);
  if( rc ){
    sqlite4DbFree(db, aProbe);
    break;
  }
  rc = sqlite4KVCursorSeek(pC->pKVCur, aProbe, nProbe, 
................................................................................
    rc = sqlite4KVCursorSeek(pC->pKVCur, pProbe, nProbe, +1);
    if( rc==SQLITE_INEXACT || rc==SQLITE_OK ){
      rc = sqlite4KVCursorKey(pC->pKVCur, &pKey, &nKey);
      if( rc==SQLITE_OK && nKey>=nProbe && memcmp(pKey, pProbe, nKey)==0 ){
        alreadyExists = 1;
        pC->nullRow = 0;
      }


    }
  }
  sqlite4DbFree(db, pFree);
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IsUnique P1 P2 P3 P4 *
**
** Cursor P1 is open on an index.
**
** The P3 register contains an integer record number. Call this record 
** number R. Register P4 is the first in a set of N contiguous registers
** that make up an unpacked index key that can be used with cursor P1.
** The value of N can be inferred from the KeyInfo.nField of the cursor.
** N includes the rowid value appended to the end of the index record.
** This rowid value may or may not be the same as R.
**
** If any of the N registers beginning with register P4 contains a NULL
** value, jump immediately to P2.
**
** Otherwise, this instruction checks if cursor P1 contains an entry
** where the first (N-1) fields match but the rowid value at the end
** of the index entry is not R. If there is no such entry (meaning that
** a row about to be inserted with rowid R is unique) then control jumps
** to instruction P2. Otherwise, the rowid of the conflicting index
** entry is copied to register P3 and control falls through to the next
** instruction.
**
** See also: NotFound, NotExists, Found
*/
case OP_IsUnique: {        /* jump, in3 */























#if 0
  u16 ii;
  VdbeCursor *pCx;
  KVCursor *pKVCur;
  u16 nField;
  Mem *aMx;
  KVByteArray *pProbe;
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
  break;
}


/* Opcode: NewRowid P1 P2 P3 * *
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number is written
** to register P2.
*/
case OP_NewRowid: {           /* out2-prerelease */
................................................................................
  ** probabilistic algorithm
  **
  ** The second algorithm is to select a rowid at random and see if
  ** it already exists in the table.  If it does not exist, we have
  ** succeeded.  If the random rowid does exist, we select a new one
  ** and try again, up to 100 times.
  */
  assert( pC->isTable );

  rc = sqlite4VdbeSeekEnd(pC, -1);
  if( rc==SQLITE_NOTFOUND ){
    v = 0;
    rc = SQLITE_OK;
  }else if( rc==SQLITE_OK ){
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
................................................................................
  KVByteArray aKey[24];

  pData = &aMem[pOp->p2];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( memIsValid(pData) );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->isTable );
  REGISTER_TRACE(pOp->p2, pData);

  if( pOp->opcode==OP_Insert ){
    pKey = &aMem[pOp->p3];
    assert( pKey->flags & MEM_Int );
    assert( memIsValid(pKey) );
    REGISTER_TRACE(pOp->p3, pKey);
................................................................................
  pOut = &aMem[pOp->p2];
  memAboutToChange(p, pOut);

  /* Note that RowKey and RowData are really exactly the same instruction */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC->isSorter==0 );
  assert( pC->isIndex || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTableReg==0 );
  assert( !pC->isSorter );
  assert( pC->pKVCur!=0 );
  pCrsr = pC->pKVCur;

................................................................................
    rc = sqlite4KVCursorKey(pCrsr, &pData, &nData);
  }else{
    rc = sqlite4KVCursorData(pCrsr, 0, -1, &pData, &nData);
  }
  if( rc==SQLITE_OK && nData>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
  sqlite4VdbeMemSetStr(pOut, (const char*)pData, nData, 0, SQLITE_DYNAMIC);
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
**
................................................................................
  if( rc==SQLITE_OK ){
    rc = sqlite4VdbeSorterWrite(db, pC, pIn2);
  }
  break;
}


/* Opcode: IdxInsert P1 P2 P3 * P5
**
** Register P2 holds the data and register P3 holds the key for an
** index record.  Write this record into the index specified by the
** cursor P1.
**
** P5 is a flag that provides a hint to the storage layer that this
** insert is likely to be an append.
**
** This instruction only works for indices.  The equivalent instruction
** for tables is OP_Insert.
*/
case OP_IdxInsert: {        /* in2 */
  VdbeCursor *pC;
  Mem *pKey;
  Mem *pData;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC );
  assert( pC->pKVCur );
  assert( pC->pKVCur->pStore );
  pKey = &aMem[pOp->p3];




  assert( pKey->flags & MEM_Blob );
  pData = &aMem[pOp->p2];
  assert( pData->flags & MEM_Blob );

  rc = sqlite4KVStoreReplace(
     pC->pKVCur->pStore,
     pKey->z, pKey->n,
     pData->z, pData->n
  );
  break;
}

/* Opcode: IdxDelete P1 P2 P3 * *
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the 
** index opened by cursor P1.
*/
case OP_IdxDelete: {
  assert( 0 );
  break;
}

/* Opcode: IdxRowid P1 P2 * * *
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1.  This integer should be
................................................................................
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: {              /* out2-prerelease */
  assert( 0 );
  break;
}

/* Opcode: IdxGE P1 P2 P3 P4 P5
**
** The P4 register values beginning with P3 form an unpacked index 
** key that omits the ROWID.  Compare this key value against the index 
** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
**
** If the P1 index entry is greater than or equal to the key value
** then jump to P2.  Otherwise fall through to the next instruction.
**
** If P5 is non-zero then the key value is increased by an epsilon 
** prior to the comparison.  This make the opcode work like IdxGT except
** that if the key from register P3 is a prefix of the key in the cursor,
** the result is false whereas it would be true with IdxGT.
*/
/* Opcode: IdxLT P1 P2 P3 P4 P5
**
** The P4 register values beginning with P3 form an unpacked index 
** key that omits the ROWID.  Compare this key value against the index 
** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
**
** If the P1 index entry is less than the key value then jump to P2.
** Otherwise fall through to the next instruction.
**
** If P5 is non-zero then the key value is increased by an epsilon prior 
** to the comparison.  This makes the opcode work like IdxLE.
*/
case OP_IdxLT:          /* jump */
case OP_IdxGE: {        /* jump */








  assert( 0 );











  break;
}

/* Opcode: Clear P1 P2 P3
**
** Delete all contents of the database table or index whose table number
** in the database file is given by P1.  
................................................................................
**
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */












































/* Opcode: RowSetAdd P1 P2 * * *
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
**
** An assertion fails if P2 is not an integer.







>
>
|



>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
<

|
|
|
>
>

<
|
>
>
>
>

<
>







 







<
<
<
<
<







 







|
|
>
>
>







 







|
>
>
>
>
>
>
>


>







 







>







 







>
>













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







 







|







 







<







 







<







 







<







 







|







 







|




<
<
<
<
<
<

|




<

<
<
<

>
>
>
>

<
|
>



|




|

|
|
<


<







 







|

|
|
|

|
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<


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







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
....
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232

2233
2234
2235
2236
2237
2238
2239

2240
2241
2242
2243
2244
2245

2246
2247
2248
2249
2250
2251
2252
2253
....
2277
2278
2279
2280
2281
2282
2283





2284
2285
2286
2287
2288
2289
2290
....
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
....
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
....
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
....
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
....
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
....
3161
3162
3163
3164
3165
3166
3167

3168
3169
3170
3171
3172
3173
3174
....
3246
3247
3248
3249
3250
3251
3252

3253
3254
3255
3256
3257
3258
3259
....
3423
3424
3425
3426
3427
3428
3429

3430
3431
3432
3433
3434
3435
3436
....
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
....
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704






3705
3706
3707
3708
3709
3710

3711



3712
3713
3714
3715
3716
3717

3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731

3732
3733

3734
3735
3736
3737
3738
3739
3740
....
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756






3757












3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
....
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
    aData = (const KVByteArray*)pReg->z;
    nData = pReg->n;
  }else{
    aData = 0;
    MemSetTypeFlag(pDest, MEM_Null);
  }
  if( rc==SQLITE_OK && aData ){
    int nField = pC->nField;
    if( pC->pKeyInfo ) nField = pC->pKeyInfo->nData;
    rc = sqlite4VdbeCreateDecoder(db, aData, nData, nField, &pCodec);
    if( rc==0 ){
      pDefault = (pOp->p4type==P4_MEM) ? pOp->p4.pMem : 0;
      rc = sqlite4VdbeDecodeValue(pCodec, pOp->p2, pDefault, pDest);
      assert( rc==SQLITE_OK );
      sqlite4VdbeDestroyDecoder(pCodec);
    }
  }else{
    sqlite4VdbeMemSetNull(pDest);
  }
  UPDATE_MAX_BLOBSIZE(pDest);
  REGISTER_TRACE(pOp->p3, pDest);
................................................................................
    assert( pIn1 <= &p->aMem[p->nMem] );
    assert( memIsValid(pIn1) );
    applyAffinity(pIn1, cAff, encoding);
    pIn1++;
  }
  break;
}

/* Opcode: MakeIdxKey P1 P2 P3 P4 *
**
** P1 is an open cursor. P2 is the first register in a contiguous array
** of N registers containing values to encode into a database key. N is
** equal to the number of columns indexed by P1, plus the number of 
** trailing primary key columns (if any).
**
** This instruction encodes the N values into a database key and writes
** the result to register P3.
**
** If P4 is of type P4_INT32, then it is a register number. This instruction
** sets register P4 to an integer value - the number of bytes in the 
** generated index key not including any appended primary key column values.
*/
case OP_MakeIdxKey: {
  VdbeCursor *pC;
  KeyInfo *pKeyInfo;
  Mem *pData0;
  u8 *aRec;                       /* The constructed database key */
  int nRec;                       /* Size of aRec[] in bytes */
  int nShort;                     /* Size of aRec[] without PK values */
  Mem *pShort;                    /* Memory cell to write nShort to */
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  memAboutToChange(p, pOut);

  rc = sqlite4VdbeEncodeKey(
    db, pData0, pKeyInfo->nField, pC->iRoot, pKeyInfo, &aRec, &nRec, &nShort
  );

  if( rc ){
    sqlite4DbFree(db, aRec);
  }else{
    if( pOp->p4type==P4_INT32 ){
      pShort = &aMem[pOp->p4.i];
      memAboutToChange(p, pShort);
      pShort->u.i = nShort;
      MemSetTypeFlag(pShort, MEM_Int);
      REGISTER_TRACE(pOp->p4.i, pShort);
    }
    rc = sqlite4VdbeMemSetStr(pOut, aRec, nRec, 0, SQLITE_DYNAMIC);
    REGISTER_TRACE(pOp->p3, pOut);
    UPDATE_MAX_BLOBSIZE(pOut);
  }

  break;
}

/* Opcode: MakeKey P1 P2 * * *
**
** This must be followed immediately by a MakeRecord opcode.  This
** opcode performs the subsequent MakeRecord and also generates
** a key for the cursor P1 and stores that key in register P2.
*/
/* Opcode: MakeRecord P1 P2 P3 P4 *
**
** This opcode uses the array of P2 registers starting at P1 as inputs.

**
** P4 may be a string that is P2 characters long, or it may be NULL. The nth 
** character of the string indicates the column affinity that should be used
** for the nth field of the index key. The mapping from character to affinity
** is given by the SQLITE_AFF_ macros defined in sqliteInt.h. If P4 is NULL
** then all index fields have the affinity NONE.
**

** This opcode expands any zero-blobs within the input array. Then if
** P4 is not NULL it applies the affinities that it specifies to the input
** array elements. Finally, if P3 is not 0, it encodes the input array
** into a data record and stores the result in register P3. The OP_Column 
** opcode can be used to decode the record.
**

** Specifying P3==0 is only useful if the previous opcode is an OP_MakeKey.
*/
case OP_MakeKey:
case OP_MakeRecord: {
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  Mem *pMem;             /* For looping over inputs */
  int nField;            /* Number of fields in the record */
................................................................................
  nField = pOp->p1;
  zAffinity = pOp->p4.z;
  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
  pData0 = &aMem[nField];
  nField = pOp->p2;
  pLast = &pData0[nField-1];






  /* Loop through the input elements.  Apply affinity to each one and
  ** expand all zero-blobs.
  */
  for(pMem=pData0; pMem<=pLast; pMem++){
    assert( memIsValid(pMem) );
    if( zAffinity ){
      applyAffinity(pMem, *(zAffinity++), encoding);
................................................................................
    }else{
      rc = sqlite4VdbeMemSetStr(pKeyOut, aRec, nRec, 0, SQLITE_DYNAMIC);
      REGISTER_TRACE(keyReg, pKeyOut);
      UPDATE_MAX_BLOBSIZE(pKeyOut);
    }
  }

  /* If P3 is not 0, compute the data rescord */
  if( rc==SQLITE_OK && pOp->p3 ){
    assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
    pOut = &aMem[pOp->p3];
    memAboutToChange(p, pOut);
    aRec = 0;
    rc = sqlite4VdbeEncodeData(db, pData0, nField, &aRec, &nRec);
    if( rc ){
      sqlite4DbFree(db, aRec);
    }else{
      rc = sqlite4VdbeMemSetStr(pOut, aRec, nRec, 0, SQLITE_DYNAMIC);
      REGISTER_TRACE(pOp->p3, pOut);
................................................................................
  VdbeCursor *pCx;

  assert( pOp->p1>=0 );
  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  rc = sqlite4KVStoreOpen(db, "ephm", ":memory:", &pCx->pTmpKV,
          SQLITE_KVOPEN_TEMPORARY | SQLITE_KVOPEN_NO_TRANSACTIONS
  );
  if( rc==SQLITE_OK ){
    rc = sqlite4KVStoreOpenCursor(pCx->pTmpKV, &pCx->pKVCur);
  }
  if( rc==SQLITE_OK ){
    rc = sqlite4KVStoreBegin(pCx->pTmpKV, 2);
  }
  pCx->pKeyInfo = pOp->p4.pKeyInfo;
  if( pCx->pKeyInfo ) pCx->pKeyInfo->enc = ENC(p->db);

  pCx->isIndex = !pCx->isTable;
  break;
}

/* Opcode: OpenSorter P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
................................................................................
  oc = pOp->opcode;
  pC->nullRow = 0;
  if( pC->isTable ){
    nField = 1;
  }else{
    nField = pOp->p4.i;
  }
  pIn3 = &aMem[pOp->p3];
  rc = sqlite4VdbeEncodeKey(db, pIn3, nField, pC->iRoot, pC->pKeyInfo,
                            &aProbe, &nProbe, 0);
  if( rc ){
    sqlite4DbFree(db, aProbe);
    break;
  }
  rc = sqlite4KVCursorSeek(pC->pKVCur, aProbe, nProbe, 
................................................................................
    rc = sqlite4KVCursorSeek(pC->pKVCur, pProbe, nProbe, +1);
    if( rc==SQLITE_INEXACT || rc==SQLITE_OK ){
      rc = sqlite4KVCursorKey(pC->pKVCur, &pKey, &nKey);
      if( rc==SQLITE_OK && nKey>=nProbe && memcmp(pKey, pProbe, nKey)==0 ){
        alreadyExists = 1;
        pC->nullRow = 0;
      }
    }else if( rc==SQLITE_NOTFOUND ){
      rc = SQLITE_OK;
    }
  }
  sqlite4DbFree(db, pFree);
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IsUnique P1 P2 P3 P4 *
**
** Cursor P1 is open on an index that enforces a UNIQUE constraint. 
** Register P3 contains an encoded key suitable to be inserted into the 
** index.
**
** Jump to instruction P2 if the encoded key can be inserted into the 
** index without violating a unique constraint. Otherwise, fall through
** to the next instruction.
*/
case OP_IsUnique: {        /* jump, in3 */
  VdbeCursor *pC;
  Mem *pShort;
  Mem *pProbe;
  int nShort;
  int dir;

  KVByteArray *aKey;              /* Key read from cursor */
  KVSize nKey;                    /* Size of aKey in bytes */

  assert( pOp->p4type==P4_INT32 );

  pProbe = &aMem[pOp->p3];
  pShort = &aMem[pOp->p4.i];
  nShort = pShort->u.i;
  pC = p->apCsr[pOp->p1];
  assert( nShort<=pProbe->n );
  assert( (nShort==pProbe->n)==(pC->pKeyInfo->nPK==0) );

  dir = (nShort < pProbe->n);
  rc = sqlite4KVCursorSeek(pC->pKVCur, pProbe->z, nShort, dir);

  if( rc==SQLITE_NOTFOUND ){
    rc = SQLITE_OK;
    pc = pOp->p2-1;
  }else if( rc==SQLITE_INEXACT ){
    assert( nShort<pProbe->n );
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE_OK ){
      if( nKey<nShort 
       || memcmp(pProbe->z, aKey, nKey)
       || (nKey==pProbe->n && 0==memcmp(pProbe->z, aKey, nKey))
      ){
        pc = pOp->p2-1;
      }
    }
  }

#if 0
  u16 ii;
  VdbeCursor *pCx;
  KVCursor *pKVCur;
  u16 nField;
  Mem *aMx;
  KVByteArray *pProbe;
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
  break;
}


/* Opcode: NewRowid P1 P2 * * *
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number is written
** to register P2.
*/
case OP_NewRowid: {           /* out2-prerelease */
................................................................................
  ** probabilistic algorithm
  **
  ** The second algorithm is to select a rowid at random and see if
  ** it already exists in the table.  If it does not exist, we have
  ** succeeded.  If the random rowid does exist, we select a new one
  ** and try again, up to 100 times.
  */


  rc = sqlite4VdbeSeekEnd(pC, -1);
  if( rc==SQLITE_NOTFOUND ){
    v = 0;
    rc = SQLITE_OK;
  }else if( rc==SQLITE_OK ){
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
................................................................................
  KVByteArray aKey[24];

  pData = &aMem[pOp->p2];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( memIsValid(pData) );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );

  REGISTER_TRACE(pOp->p2, pData);

  if( pOp->opcode==OP_Insert ){
    pKey = &aMem[pOp->p3];
    assert( pKey->flags & MEM_Int );
    assert( memIsValid(pKey) );
    REGISTER_TRACE(pOp->p3, pKey);
................................................................................
  pOut = &aMem[pOp->p2];
  memAboutToChange(p, pOut);

  /* Note that RowKey and RowData are really exactly the same instruction */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC->isSorter==0 );

  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTableReg==0 );
  assert( !pC->isSorter );
  assert( pC->pKVCur!=0 );
  pCrsr = pC->pKVCur;

................................................................................
    rc = sqlite4KVCursorKey(pCrsr, &pData, &nData);
  }else{
    rc = sqlite4KVCursorData(pCrsr, 0, -1, &pData, &nData);
  }
  if( rc==SQLITE_OK && nData>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
  sqlite4VdbeMemSetStr(pOut, (const char*)pData, nData, 0, SQLITE_TRANSIENT);
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
**
................................................................................
  if( rc==SQLITE_OK ){
    rc = sqlite4VdbeSorterWrite(db, pC, pIn2);
  }
  break;
}


/* Opcode: IdxInsert P1 P2 P3 * *
**
** Register P2 holds the data and register P3 holds the key for an
** index record.  Write this record into the index specified by the
** cursor P1.






*/
case OP_IdxInsert: {
  VdbeCursor *pC;
  Mem *pKey;
  Mem *pData;


  pC = p->apCsr[pOp->p1];



  pKey = &aMem[pOp->p3];
  pData = pOp->p2 ? &aMem[pOp->p2] : 0;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pC && pC->pKVCur && pC->pKVCur->pStore );
  assert( pKey->flags & MEM_Blob );

  assert( pData==0 || (pData->flags & MEM_Blob) );

  rc = sqlite4KVStoreReplace(
     pC->pKVCur->pStore,
     pKey->z, pKey->n,
     (pData ? pData->z : 0), (pData ? pData->n : 0)
  );
  break;
}

/* Opcode: IdxDelete P1 * P3 * *
**
** P1 is a cursor open on a database index. P3 contains a key suitable for
** the index. Delete P3 from P1.

*/
case OP_IdxDelete: {

  break;
}

/* Opcode: IdxRowid P1 P2 * * *
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1.  This integer should be
................................................................................
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: {              /* out2-prerelease */
  assert( 0 );
  break;
}

/* Opcode: IdxGE P1 P2 P3
**
** P1 is an open cursor. P3 contains a database key formatted by MakeKey.
** This opcode compares the current key that index P1 points to with
** the key in register P3.
**
** If the index key is greater than...






*/












case OP_IdxLT:          /* jump */
case OP_IdxGE: {        /* jump */
  VdbeCursor *pC;
  KVByteArray *aKey;              /* Key from cursor P1 */
  KVSize nKey;                    /* Size of aKey[] in bytes */
  Mem *pCmp;
  int nCmp;
  int res;

  pCmp = &aMem[pOp->p3];
  assert( pCmp->flags & MEM_Blob );
  pC = p->apCsr[pOp->p1];
  rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
  if( rc==SQLITE_OK ){
    nCmp = pCmp->n;
    if( nCmp>nKey ) nCmp = nKey;

    res = memcmp(aKey, pCmp->z, nCmp);
    if( res>0 ){
      pc = pOp->p2 - 1;
    }
  }
  break;
}

/* Opcode: Clear P1 P2 P3
**
** Delete all contents of the database table or index whose table number
** in the database file is given by P1.  
................................................................................
**
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: KeySetAdd P1 P2 * * *
**
** Read the blob value from register P2 and store it in KeySet object P1.
*/
case OP_KeySetAdd: {         /* in1, in2 */
  pIn1 = &aMem[pOp->p1];
  if( (pIn1->flags & MEM_KeySet)==0 ){
    sqlite4VdbeMemSetKeySet(pIn1);
    if( (pIn1->flags & MEM_KeySet)==0 ) goto no_mem;
  }
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  sqlite4KeySetInsert(pIn1->u.pKeySet, pIn2->z, pIn2->n);
  break;
}

/* Opcode: KeySetRead P1 P2 P3 * *
**
** Remove a value from MemSet object P1 and store it in register P3.
** Or, if MemSet P1 is already empty, leave P3 unchanged and jump to 
** instruction P2.
*/
case OP_KeySetRead: {       /* in1 */
  const char *aKey;
  int nKey;

  CHECK_FOR_INTERRUPT;
  pIn1 = &aMem[pOp->p1];
  pOut = &aMem[pOp->p3];
  if( (pIn1->flags & MEM_KeySet)
   && (aKey = sqlite4KeySetRead(pIn1->u.pKeySet, &nKey))
  ){
    rc = sqlite4VdbeMemSetStr(pOut, aKey, nKey, 0, SQLITE_TRANSIENT);
    sqlite4KeySetNext(pIn1->u.pKeySet);
  }else{
    /* The KeySet is empty */
    sqlite4VdbeMemSetNull(pIn1);
    pc = pOp->p2 - 1;
  }

  break;
}

/* Opcode: RowSetAdd P1 P2 * * *
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
**
** An assertion fails if P2 is not an integer.

Changes to src/vdbeInt.h.

136
137
138
139
140
141
142

143
144
145
146
147
148
149
...
171
172
173
174
175
176
177


178
179
180
181
182
183
184
  char *z;            /* String or BLOB value */
  double r;           /* Real value */
  union {
    i64 i;              /* Integer value used when MEM_Int is set in flags */
    int nZero;          /* Used when bit MEM_Zero is set in flags */
    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */

    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
  } u;
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
#ifdef SQLITE_DEBUG
................................................................................
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_RowSet    0x0020   /* Value is a RowSet object */
#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
#define MEM_Invalid   0x0080   /* Value is undefined */
#define MEM_TypeMask  0x00ff   /* Mask of type bits */



/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0200   /* String rep is nul terminated */







>







 







>
>







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  char *z;            /* String or BLOB value */
  double r;           /* Real value */
  union {
    i64 i;              /* Integer value used when MEM_Int is set in flags */
    int nZero;          /* Used when bit MEM_Zero is set in flags */
    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
    KeySet *pKeySet;    /* Used only when flags==MEM_KeySet */
    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
  } u;
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
#ifdef SQLITE_DEBUG
................................................................................
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_RowSet    0x0020   /* Value is a RowSet object */
#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
#define MEM_Invalid   0x0080   /* Value is undefined */
#define MEM_TypeMask  0x00ff   /* Mask of type bits */

#define MEM_KeySet    0x0020   /* Value is a KeySet object */

/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0200   /* String rep is nul terminated */

Changes to src/vdbeaux.c.

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
      ** callgrind, this causes a certain test case to hit the CPU 4.7 
      ** percent less (x86 linux, gcc version 4.1.2, -O6) than if 
      ** sqlite4MemRelease() were called from here. With -O2, this jumps
      ** to 6.6 percent. The test case is inserting 1000 rows into a table 
      ** with no indexes using a single prepared INSERT statement, bind() 
      ** and reset(). Inserts are grouped into a transaction.
      */
      if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
        sqlite4VdbeMemRelease(p);
      }else if( p->zMalloc ){
        sqlite4DbFree(db, p->zMalloc);
        p->zMalloc = 0;
      }

      p->flags = MEM_Invalid;







|







1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
      ** callgrind, this causes a certain test case to hit the CPU 4.7 
      ** percent less (x86 linux, gcc version 4.1.2, -O6) than if 
      ** sqlite4MemRelease() were called from here. With -O2, this jumps
      ** to 6.6 percent. The test case is inserting 1000 rows into a table 
      ** with no indexes using a single prepared INSERT statement, bind() 
      ** and reset(). Inserts are grouped into a transaction.
      */
      if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_KeySet) ){
        sqlite4VdbeMemRelease(p);
      }else if( p->zMalloc ){
        sqlite4DbFree(db, p->zMalloc);
        p->zMalloc = 0;
      }

      p->flags = MEM_Invalid;

Changes to src/vdbecodec.c.

104
105
106
107
108
109
110


111
112
113
114
115
116
117
...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
...
617
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
    }else if( type<=10 ){
      size = type - 2;
    }else{
      size = type - 9;
    }
    if( i<iVal ){
      ofst += size;


    }else if( type<=2 ){
      sqlite4VdbeMemSetInt64(pOut, type-1);
    }else if( type<=10 ){
      sqlite4_int64 v = ((char*)p->a)[ofst];
      for(i=4; i<type; i++){
        v = v*256 + p->a[ofst+i-3];
      }
................................................................................
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int iTabno,                  /* The table this key applies to */
  KeyInfo *pKeyInfo,           /* Collating sequence information */
  u8 **paOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int *pnShort                 /* Number of bytes without the primary key */
){
  int i;
  int rc = SQLITE_OK;
  KeyEncoder x;
................................................................................
    nField = 1;
    iShort = 0;
    xColl = &defaultColl;
    aColl = &xColl;
    so = 0;
  }
  for(i=0; i<nField && rc==SQLITE_OK; i++){
    if( pnShort && i==iShort ) *pnShort = x.nOut;
    rc = encodeOneKeyValue(&x, aIn+i, so ? so[i] : SQLITE_SO_ASC, aColl[i]);

  }
  if( rc ){
    sqlite4DbFree(db, x.aOut);
  }else{
    *paOut = x.aOut;
    *pnOut = x.nOut;
  }







>
>







 







|







 







<

>







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
...
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633
634
    }else if( type<=10 ){
      size = type - 2;
    }else{
      size = type - 9;
    }
    if( i<iVal ){
      ofst += size;
    }else if( type==0 ){
      /* no-op */
    }else if( type<=2 ){
      sqlite4VdbeMemSetInt64(pOut, type-1);
    }else if( type<=10 ){
      sqlite4_int64 v = ((char*)p->a)[ofst];
      for(i=4; i<type; i++){
        v = v*256 + p->a[ofst+i-3];
      }
................................................................................
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int iTabno,                  /* The table this key applies to */
  KeyInfo *pKeyInfo,           /* Collating sequence and sort-order info */
  u8 **paOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int *pnShort                 /* Number of bytes without the primary key */
){
  int i;
  int rc = SQLITE_OK;
  KeyEncoder x;
................................................................................
    nField = 1;
    iShort = 0;
    xColl = &defaultColl;
    aColl = &xColl;
    so = 0;
  }
  for(i=0; i<nField && rc==SQLITE_OK; i++){

    rc = encodeOneKeyValue(&x, aIn+i, so ? so[i] : SQLITE_SO_ASC, aColl[i]);
    if( pnShort && i+1==iShort ) *pnShort = x.nOut;
  }
  if( rc ){
    sqlite4DbFree(db, x.aOut);
  }else{
    *paOut = x.aOut;
    *pnOut = x.nOut;
  }

Changes to src/vdbemem.c.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
...
517
518
519
520
521
522
523










524
525
526
527
528
529
530
**
** SQLITE_OK is returned if the conversion is successful (or not required).
** SQLITE_NOMEM may be returned if a malloc() fails during conversion
** between formats.
*/
int sqlite4VdbeChangeEncoding(Mem *pMem, int desiredEnc){
  int rc;
  assert( (pMem->flags&MEM_RowSet)==0 );
  assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
           || desiredEnc==SQLITE_UTF16BE );
  if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
    return SQLITE_OK;
  }
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
#ifdef SQLITE_OMIT_UTF16
................................................................................
int sqlite4VdbeMemGrow(Mem *pMem, int n, int preserve){
  assert( 1 >=
    ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
    (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + 
    ((pMem->flags&MEM_Ephem) ? 1 : 0) + 
    ((pMem->flags&MEM_Static) ? 1 : 0)
  );
  assert( (pMem->flags&MEM_RowSet)==0 );

  if( n<32 ) n = 32;
  if( sqlite4DbMallocSize(pMem->db, pMem->zMalloc)<n ){
    if( preserve && pMem->z==pMem->zMalloc ){
      pMem->z = pMem->zMalloc = sqlite4DbReallocOrFree(pMem->db, pMem->z, n);
      preserve = 0;
    }else{
................................................................................
** overwritten or altered.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite4VdbeMemMakeWriteable(Mem *pMem){
  int f;
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  ExpandBlob(pMem);
  f = pMem->flags;
  if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
    if( sqlite4VdbeMemGrow(pMem, pMem->n + 2, 1) ){
      return SQLITE_NOMEM;
    }
    pMem->z[pMem->n] = 0;
................................................................................
  int fg = pMem->flags;
  const int nByte = 32;

  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( !(fg&MEM_Zero) );
  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( (pMem->flags&MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite4VdbeMemGrow(pMem, nByte, 0) ){
    return SQLITE_NOMEM;
  }

................................................................................
void sqlite4VdbeMemReleaseExternal(Mem *p){
  assert( p->db==0 || sqlite4_mutex_held(p->db->mutex) );
  if( p->flags&MEM_Agg ){
    sqlite4VdbeMemFinalize(p, p->u.pDef);
    assert( (p->flags & MEM_Agg)==0 );
    sqlite4VdbeMemRelease(p);
  }else if( p->flags&MEM_Dyn && p->xDel ){
    assert( (p->flags&MEM_RowSet)==0 );
    assert( p->xDel!=SQLITE_DYNAMIC );
    p->xDel((void *)p->z);
    p->xDel = 0;
  }else if( p->flags&MEM_RowSet ){
    sqlite4RowSetClear(p->u.pRowSet);
  }else if( p->flags&MEM_Frame ){
    sqlite4VdbeMemSetNull(p);
  }
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
................................................................................
*/
void sqlite4VdbeMemSetNull(Mem *pMem){
  if( pMem->flags & MEM_Frame ){
    VdbeFrame *pFrame = pMem->u.pFrame;
    pFrame->pParent = pFrame->v->pDelFrame;
    pFrame->v->pDelFrame = pFrame;
  }
  if( pMem->flags & MEM_RowSet ){
    sqlite4RowSetClear(pMem->u.pRowSet);
  }
  MemSetTypeFlag(pMem, MEM_Null);
  pMem->type = SQLITE_NULL;
}

/*
** Delete any previous value and set the value to be a BLOB of length
................................................................................
    assert( pMem->zMalloc );
    pMem->u.pRowSet = sqlite4RowSetInit(db, pMem->zMalloc, 
                                       sqlite4DbMallocSize(db, pMem->zMalloc));
    assert( pMem->u.pRowSet!=0 );
    pMem->flags = MEM_RowSet;
  }
}











/*
** Return true if the Mem object contains a TEXT or BLOB that is
** too large - whose size exceeds SQLITE_MAX_LENGTH.
*/
int sqlite4VdbeMemTooBig(Mem *p){
  assert( p->db!=0 );







|







 







|







 







|







 







|







 







|



|
|







 







|
|







 







>
>
>
>
>
>
>
>
>
>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
**
** SQLITE_OK is returned if the conversion is successful (or not required).
** SQLITE_NOMEM may be returned if a malloc() fails during conversion
** between formats.
*/
int sqlite4VdbeChangeEncoding(Mem *pMem, int desiredEnc){
  int rc;
  assert( (pMem->flags&MEM_KeySet)==0 );
  assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
           || desiredEnc==SQLITE_UTF16BE );
  if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
    return SQLITE_OK;
  }
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
#ifdef SQLITE_OMIT_UTF16
................................................................................
int sqlite4VdbeMemGrow(Mem *pMem, int n, int preserve){
  assert( 1 >=
    ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
    (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + 
    ((pMem->flags&MEM_Ephem) ? 1 : 0) + 
    ((pMem->flags&MEM_Static) ? 1 : 0)
  );
  assert( (pMem->flags&MEM_KeySet)==0 );

  if( n<32 ) n = 32;
  if( sqlite4DbMallocSize(pMem->db, pMem->zMalloc)<n ){
    if( preserve && pMem->z==pMem->zMalloc ){
      pMem->z = pMem->zMalloc = sqlite4DbReallocOrFree(pMem->db, pMem->z, n);
      preserve = 0;
    }else{
................................................................................
** overwritten or altered.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite4VdbeMemMakeWriteable(Mem *pMem){
  int f;
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags&MEM_KeySet)==0 );
  ExpandBlob(pMem);
  f = pMem->flags;
  if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
    if( sqlite4VdbeMemGrow(pMem, pMem->n + 2, 1) ){
      return SQLITE_NOMEM;
    }
    pMem->z[pMem->n] = 0;
................................................................................
  int fg = pMem->flags;
  const int nByte = 32;

  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( !(fg&MEM_Zero) );
  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );
  assert( (pMem->flags&MEM_KeySet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );


  if( sqlite4VdbeMemGrow(pMem, nByte, 0) ){
    return SQLITE_NOMEM;
  }

................................................................................
void sqlite4VdbeMemReleaseExternal(Mem *p){
  assert( p->db==0 || sqlite4_mutex_held(p->db->mutex) );
  if( p->flags&MEM_Agg ){
    sqlite4VdbeMemFinalize(p, p->u.pDef);
    assert( (p->flags & MEM_Agg)==0 );
    sqlite4VdbeMemRelease(p);
  }else if( p->flags&MEM_Dyn && p->xDel ){
    assert( (p->flags&MEM_KeySet)==0 );
    assert( p->xDel!=SQLITE_DYNAMIC );
    p->xDel((void *)p->z);
    p->xDel = 0;
  }else if( p->flags&MEM_KeySet ){
    sqlite4KeySetFree(p->u.pKeySet);
  }else if( p->flags&MEM_Frame ){
    sqlite4VdbeMemSetNull(p);
  }
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
................................................................................
*/
void sqlite4VdbeMemSetNull(Mem *pMem){
  if( pMem->flags & MEM_Frame ){
    VdbeFrame *pFrame = pMem->u.pFrame;
    pFrame->pParent = pFrame->v->pDelFrame;
    pFrame->v->pDelFrame = pFrame;
  }
  if( pMem->flags & MEM_KeySet ){
    sqlite4KeySetFree(pMem->u.pKeySet);
  }
  MemSetTypeFlag(pMem, MEM_Null);
  pMem->type = SQLITE_NULL;
}

/*
** Delete any previous value and set the value to be a BLOB of length
................................................................................
    assert( pMem->zMalloc );
    pMem->u.pRowSet = sqlite4RowSetInit(db, pMem->zMalloc, 
                                       sqlite4DbMallocSize(db, pMem->zMalloc));
    assert( pMem->u.pRowSet!=0 );
    pMem->flags = MEM_RowSet;
  }
}

void sqlite4VdbeMemSetKeySet(Mem *pMem){
  sqlite4 *db = pMem->db;
  assert( db!=0 );
  assert( (pMem->flags & MEM_KeySet)==0 );
  sqlite4VdbeMemRelease(pMem);

  pMem->u.pKeySet = sqlite4KeySetInit(db);
  pMem->flags = MEM_KeySet;
}

/*
** Return true if the Mem object contains a TEXT or BLOB that is
** too large - whose size exceeds SQLITE_MAX_LENGTH.
*/
int sqlite4VdbeMemTooBig(Mem *p){
  assert( p->db!=0 );

Changes to src/where.c.

2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
....
2902
2903
2904
2905
2906
2907
2908








2909
2910

2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940





2941
2942
2943
2944

2945
2946
2947
2948
2949
2950
2951
....
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
....
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
....
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116





3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131


3132
3133
3134
3135
3136
3137
3138
....
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
....
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
....
4053
4054
4055
4056
4057
4058
4059

4060
4061
4062
4063
4064
4065
4066
....
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163








4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186







4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198

4199
4200
4201
4202
4203
4204
4205
4206
....
4212
4213
4214
4215
4216
4217
4218
4219

4220
4221
4222
4223
4224
4225
4226
....
4230
4231
4232
4233
4234
4235
4236

4237
4238
4239
4240
4241
4242
4243
....
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004

5005
5006
5007
5008
5009
5010
5011
5012

5013
5014
5015
5016
5017
5018
5019
5020
5021
5022



5023
5024
5025
5026
5027
5028
5029

5030
5031
5032
5033
5034
5035
5036
....
5180
5181
5182
5183
5184
5185
5186

5187

5188
5189
5190
5191
5192
5193
5194
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  ExprList *pDistinct,        /* The select-list if query is DISTINCT */
  WhereCost *pCost            /* Lowest cost query plan */
){
  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  Index *pProbe;              /* An index we are evaluating */
  Index *pIdx;                /* Copy of pProbe, or zero for IPK index */
  int eqTermMask;             /* Current mask of valid equality operators */
  int idxEqTermMask;          /* Index mask of valid equality operators */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  int wsFlagMask;             /* Allowed flags in pCost->plan.wsFlag */

  /* Initialize the cost to a worst-case value */
  memset(pCost, 0, sizeof(*pCost));
  pCost->rCost = SQLITE_BIG_DBL;

  /* If the pSrc table is the right table of a LEFT JOIN then we may not
................................................................................
  */
  if( pSrc->jointype & JT_LEFT ){
    idxEqTermMask = WO_EQ|WO_IN;
  }else{
    idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
  }









  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */

    pIdx = pProbe = pSrc->pIndex;
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this
    ** fake index the first in a chain of Index objects with all of the real
    ** indices to follow */
    Index *pFirst;                  /* First of real indices on the table */
    memset(&sPk, 0, sizeof(Index));
    sPk.nColumn = 1;
    sPk.aiColumn = &aiColumnPk;
    sPk.aiRowEst = aiRowEstPk;
    sPk.onError = OE_Replace;
    sPk.pTable = pSrc->pTab;
    aiRowEstPk[0] = pSrc->pTab->nRowEst;
    aiRowEstPk[1] = 1;
    pFirst = pSrc->pTab->pIndex;
    if( pSrc->notIndexed==0 ){
      /* The real indices of the table are only considered if the
      ** NOT INDEXED qualifier is omitted from the FROM clause */
      sPk.pNext = pFirst;
    }
    pProbe = &sPk;
    wsFlagMask = ~(
        WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
    );
    eqTermMask = WO_EQ|WO_IN;
    pIdx = 0;
  }






  /* Loop over all indices looking for the best one to use
  */
  for(; pProbe; pIdx=pProbe=pProbe->pNext){

    const tRowcnt * const aiRowEst = pProbe->aiRowEst;
    double cost;                /* Cost of using pProbe */
    double nRow;                /* Estimated number of rows in result set */
    double log10N = (double)1;  /* base-10 logarithm of nRow (inexact) */
    int rev;                    /* True to scan in reverse order */
    int wsFlags = 0;
    Bitmask used = 0;
................................................................................
#ifdef SQLITE_ENABLE_STAT3
    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
#endif

    /* Determine the values of nEq and nInMul */
    for(nEq=0; nEq<pProbe->nColumn; nEq++){
      int j = pProbe->aiColumn[nEq];
      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
      if( pTerm==0 ) break;
      wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
      testcase( pTerm->pWC!=pWC );
      if( pTerm->eOperator & WO_IN ){
        Expr *pExpr = pTerm->pExpr;
        wsFlags |= WHERE_COLUMN_IN;
        if( ExprHasProperty(pExpr, EP_xIsSelect) ){
................................................................................
      testcase( wsFlags & WHERE_COLUMN_IN );
      testcase( wsFlags & WHERE_COLUMN_NULL );
      if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
        wsFlags |= WHERE_UNIQUE;
      }
    }else if( pProbe->bUnordered==0 ){
      int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]);
      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
        if( pTop ){
          nBound = 1;
          wsFlags |= WHERE_TOP_LIMIT;
          used |= pTop->prereqRight;
          testcase( pTop->pWC!=pWC );
        }
................................................................................
    ** order of the DISTINCT expressions, clear bDist and set the appropriate
    ** flags in wsFlags. */
    if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) ){
      bDist = 0;
      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
    }

    /* If currently calculating the cost of using an index (not the IPK
    ** index), determine if all required column data may be obtained without 
    ** using the main table (i.e. if the index is a covering
    ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
    ** wsFlags. Otherwise, set the bLookup variable to true.  */





    if( pIdx && wsFlags ){
      Bitmask m = pSrc->colUsed;
      int j;
      for(j=0; j<pIdx->nColumn; j++){
        int x = pIdx->aiColumn[j];
        if( x<BMS-1 ){
          m &= ~(((Bitmask)1)<<x);
        }
      }
      if( m==0 ){
        wsFlags |= WHERE_IDX_ONLY;
      }else{
        bLookup = 1;
      }
    }



    /*
    ** Estimate the number of rows of output.  For an "x IN (SELECT...)"
    ** constraint, do not let the estimate exceed half the rows in the table.
    */
    nRow = (double)(aiRowEst[nEq] * nInMul);
    if( bInEst && nRow*2>aiRowEst[0] ){
................................................................................
      ** decision and one which we expect to revisit in the future.  But
      ** it seems to be working well enough at the moment.
      */
      cost = aiRowEst[0]*4;
    }else{
      log10N = estLog(aiRowEst[0]);
      cost = nRow;
      if( pIdx ){
        if( bLookup ){
          /* For an index lookup followed by a table lookup:
          **    nInMul index searches to find the start of each index range
          **  + nRow steps through the index
          **  + nRow table searches to lookup the table entry using the rowid
          */
          cost += (nInMul + nRow)*log10N;
        }else{
          /* For a covering index:
          **     nInMul index searches to find the initial entry 
          **   + nRow steps through the index
          */
          cost += nInMul*log10N;
        }
      }else{
        /* For a rowid primary key lookup:
        **    nInMult table searches to find the initial entry for each range
        **  + nRow steps through the table
        */
        cost += nInMul*log10N;
      }
    }

    /* Add in the estimated cost of sorting the result.  Actual experimental
    ** measurements of sorting performance in SQLite show that sorting time
................................................................................
      if( nRow<2 ) nRow = 2;
    }


    WHERETRACE((
      "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
      "         notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), 
      nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
      notReady, log10N, nRow, cost, used
    ));

    /* If this index is the best we have seen so far, then record this
    ** index and its cost in the pCost structure.
    */
    if( (!pIdx || wsFlags)
     && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow))
    ){
      pCost->rCost = cost;
      pCost->used = used;
      pCost->plan.nRow = nRow;
      pCost->plan.wsFlags = (wsFlags&wsFlagMask);
      pCost->plan.nEq = nEq;
      pCost->plan.u.pIdx = pIdx;
    }

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;

    /* Reset masks for the next index in the loop */
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }

  /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
................................................................................
    int nConstraint;             /* Number of constraint terms */
    Index *pIdx;                 /* The index we will be using */
    int iIdxCur;                 /* The VDBE cursor for the index */
    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff;               /* Affinity for end of range constraint */


    pIdx = pLevel->plan.u.pIdx;
    iIdxCur = pLevel->iIdxCur;
    k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]);

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
................................................................................
    testcase( op==OP_Last );
    testcase( op==OP_SeekGt );
    testcase( op==OP_SeekGe );
    testcase( op==OP_SeekLe );
    testcase( op==OP_SeekLt );
    sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);

    /* Load the value for the inequality constraint at the end of the
    ** range (if any).
    */








    nConstraint = nEq;
    if( pRangeEnd ){
      Expr *pRight = pRangeEnd->pExpr->pRight;
      sqlite4ExprCacheRemove(pParse, regBase+nEq, 1);
      sqlite4ExprCode(pParse, pRight, regBase+nEq);
      if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
        sqlite4ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
      }
      if( zEndAff ){
        if( sqlite4CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){
          /* Since the comparison is to be performed with no conversions
          ** applied to the operands, set the affinity to apply to pRight to 
          ** SQLITE_AFF_NONE.  */
          zEndAff[nEq] = SQLITE_AFF_NONE;
        }
        if( sqlite4ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
          zEndAff[nEq] = SQLITE_AFF_NONE;
        }
      }  
      codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
      nConstraint++;
      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    }







    sqlite4DbFree(pParse->db, zStartAff);
    sqlite4DbFree(pParse->db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);

    /* Check if the index cursor is past the end of the range. */
    op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
    testcase( op==OP_Noop );
    testcase( op==OP_IdxGE );
    testcase( op==OP_IdxLT );
    if( op!=OP_Noop ){

      sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
      sqlite4VdbeChangeP5(v, endEq!=bRev ?1:0);
    }

    /* If there are inequality constraints, check that the value
    ** of the table column that the inequality contrains is not NULL.
    ** If it is, jump to the next iteration of the loop.
    */
................................................................................
      sqlite4VdbeAddOp2(v, OP_IsNull, r1, addrCont);
    }
    sqlite4ReleaseTempReg(pParse, r1);

    /* Seek the table cursor, if required */
    disableTerm(pLevel, pRangeStart);
    disableTerm(pLevel, pRangeEnd);
    if( !omitTable ){

      iRowidReg = iReleaseReg = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
      sqlite4ExprCacheStore(pParse, iCur, -1, iRowidReg);
      sqlite4VdbeAddOp2(v, OP_Seek, iCur, iRowidReg);  /* Deferred seek */
    }

    /* Record the instruction used to terminate the loop. Disable 
................................................................................
      pLevel->op = OP_Noop;
    }else if( bRev ){
      pLevel->op = OP_Prev;
    }else{
      pLevel->op = OP_Next;
    }
    pLevel->p1 = iIdxCur;

  }else

#ifndef SQLITE_OMIT_OR_OPTIMIZATION
  if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
    /* Case 4:  Two or more separately indexed terms connected by OR
    **
    ** Example:
................................................................................
      int iCur = pTabItem->iCursor;
      sqlite4VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
         && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
      int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
      sqlite4OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
      testcase( pTab->nCol==BMS-1 );
      testcase( pTab->nCol==BMS );

      if( !pWInfo->okOnePass && pTab->nCol<BMS ){
        Bitmask b = pTabItem->colUsed;
        int n = 0;
        for(; b; b=b>>1, n++){}
        sqlite4VdbeChangeP4(v, sqlite4VdbeCurrentAddr(v)-1, 
                            SQLITE_INT_TO_PTR(n), P4_INT32);
        assert( n<=pTab->nCol );
      }

    }else{
      sqlite4TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
      constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
      Index *pIx = pLevel->plan.u.pIdx;



      KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIx);
      int iIdxCur = pLevel->iIdxCur;
      assert( pIx->pSchema==pTab->pSchema );
      assert( iIdxCur>=0 );
      sqlite4VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
                        (char*)pKey, P4_KEYINFO_HANDOFF);
      VdbeComment((v, "%s", pIx->zName));

    }
    sqlite4CodeVerifySchema(pParse, iDb);
    notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor);
  }
  pWInfo->iTop = sqlite4VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;

................................................................................
     && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
    ){
      int ws = pLevel->plan.wsFlags;
      if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
        sqlite4VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
      }
      if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){

        sqlite4VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);

      }
    }

    /* If this scan uses an index, make code substitutions to read data
    ** from the index in preference to the table. Sometimes, this means
    ** the table need never be read from. This is a performance boost,
    ** as the vdbe level waits until the table is read before actually







|


<
<
<







 







>
>
>
>
>
>
>
>


>
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|

>
>
>
>
>

|
<
<
>







 







|







 







|
|
|







 







|



|
>
>
>
>
>
|


|
|










>
>







 







<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<







 







|







|







|


|

|







 







>







 







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






<
<
<
<
<

>
|







 







|
>







 







>







 







|


>








>










>
>
>
|
|
|
|
|
|
|
>







 







>
|
>







2879
2880
2881
2882
2883
2884
2885
2886
2887
2888



2889
2890
2891
2892
2893
2894
2895
....
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920




















2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933


2934
2935
2936
2937
2938
2939
2940
2941
....
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
....
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
....
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
....
3186
3187
3188
3189
3190
3191
3192

3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203







3204
3205
3206
3207
3208
3209
3210
....
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
....
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
....
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197





4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
....
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
....
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
....
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
....
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  ExprList *pDistinct,        /* The select-list if query is DISTINCT */
  WhereCost *pCost            /* Lowest cost query plan */
){
  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  Index *pProbe;              /* An index we are evaluating */
  Index *pFirst;              /* First index to evaluate */
  int eqTermMask;             /* Current mask of valid equality operators */
  int idxEqTermMask;          /* Index mask of valid equality operators */



  int wsFlagMask;             /* Allowed flags in pCost->plan.wsFlag */

  /* Initialize the cost to a worst-case value */
  memset(pCost, 0, sizeof(*pCost));
  pCost->rCost = SQLITE_BIG_DBL;

  /* If the pSrc table is the right table of a LEFT JOIN then we may not
................................................................................
  */
  if( pSrc->jointype & JT_LEFT ){
    idxEqTermMask = WO_EQ|WO_IN;
  }else{
    idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
  }

  /* Normally, this function considers all indexes attached to the table
  ** being queried. Except, if an INDEXED BY clause is specified then only
  ** the named index is considered. And if a NOT INDEXED clause was present
  ** only the PRIMARY KEY index may be considered.  
  */
  assert( pSrc->notIndexed==0 && "TODO: Re-enable this" );
  assert( pSrc->pIndex==0 && "TODO: Re-enable this" );
#if 0
  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    assert(!"TODO: Fix this");
    pFirst = pSrc->pIndex;
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }else{




















    wsFlagMask = ~(
        WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
    );
    eqTermMask = WO_EQ|WO_IN;
    pFirst = pSrc->pTab->pIndex;
  }
#else
  wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
  eqTermMask = idxEqTermMask;
  pFirst = pSrc->pTab->pIndex;
#endif

  /* Loop over all indices looking for the best one to use */


  for(pProbe=pFirst; pProbe; pProbe=pProbe->pNext){
    const tRowcnt * const aiRowEst = pProbe->aiRowEst;
    double cost;                /* Cost of using pProbe */
    double nRow;                /* Estimated number of rows in result set */
    double log10N = (double)1;  /* base-10 logarithm of nRow (inexact) */
    int rev;                    /* True to scan in reverse order */
    int wsFlags = 0;
    Bitmask used = 0;
................................................................................
#ifdef SQLITE_ENABLE_STAT3
    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
#endif

    /* Determine the values of nEq and nInMul */
    for(nEq=0; nEq<pProbe->nColumn; nEq++){
      int j = pProbe->aiColumn[nEq];
      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe);
      if( pTerm==0 ) break;
      wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
      testcase( pTerm->pWC!=pWC );
      if( pTerm->eOperator & WO_IN ){
        Expr *pExpr = pTerm->pExpr;
        wsFlags |= WHERE_COLUMN_IN;
        if( ExprHasProperty(pExpr, EP_xIsSelect) ){
................................................................................
      testcase( wsFlags & WHERE_COLUMN_IN );
      testcase( wsFlags & WHERE_COLUMN_NULL );
      if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
        wsFlags |= WHERE_UNIQUE;
      }
    }else if( pProbe->bUnordered==0 ){
      int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]);
      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe) ){
        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe);
        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe);
        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
        if( pTop ){
          nBound = 1;
          wsFlags |= WHERE_TOP_LIMIT;
          used |= pTop->prereqRight;
          testcase( pTop->pWC!=pWC );
        }
................................................................................
    ** order of the DISTINCT expressions, clear bDist and set the appropriate
    ** flags in wsFlags. */
    if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) ){
      bDist = 0;
      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
    }

    /* If currently calculating the cost of using an index (not the PK
    ** index), determine if all required column data may be obtained without 
    ** using the main table (i.e. if the index is a covering
    ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
    ** wsFlags. Otherwise, set the bLookup variable to true.  
    **
    ** TODO: Not clear if this optimization can be applied in SQLite 4. Fix
    ** this block once that is figured out.
    */
#if 0
    if( wsFlags ){
      Bitmask m = pSrc->colUsed;
      int j;
      for(j=0; j<pProbe->nColumn; j++){
        int x = pProbe->aiColumn[j];
        if( x<BMS-1 ){
          m &= ~(((Bitmask)1)<<x);
        }
      }
      if( m==0 ){
        wsFlags |= WHERE_IDX_ONLY;
      }else{
        bLookup = 1;
      }
    }
#endif
    bLookup = (pProbe->eIndexType!=SQLITE_INDEX_PRIMARYKEY);

    /*
    ** Estimate the number of rows of output.  For an "x IN (SELECT...)"
    ** constraint, do not let the estimate exceed half the rows in the table.
    */
    nRow = (double)(aiRowEst[nEq] * nInMul);
    if( bInEst && nRow*2>aiRowEst[0] ){
................................................................................
      ** decision and one which we expect to revisit in the future.  But
      ** it seems to be working well enough at the moment.
      */
      cost = aiRowEst[0]*4;
    }else{
      log10N = estLog(aiRowEst[0]);
      cost = nRow;

      if( bLookup ){
        /* For an index lookup followed by a table lookup:
        **    nInMul index searches to find the start of each index range
        **  + nRow steps through the index
        **  + nRow table searches to lookup the table entry using the PK
        */
        cost += (nInMul + nRow)*log10N;
      }else{
        /* For a covering index:
        **     nInMul index searches to find the initial entry 
        **   + nRow steps through the index







        */
        cost += nInMul*log10N;
      }
    }

    /* Add in the estimated cost of sorting the result.  Actual experimental
    ** measurements of sorting performance in SQLite show that sorting time
................................................................................
      if( nRow<2 ) nRow = 2;
    }


    WHERETRACE((
      "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
      "         notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
      pSrc->pTab->zName, pProbe->zName,
      nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
      notReady, log10N, nRow, cost, used
    ));

    /* If this index is the best we have seen so far, then record this
    ** index and its cost in the pCost structure.
    */
    if( (pProbe==pFirst || wsFlags)
     && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow))
    ){
      pCost->rCost = cost;
      pCost->used = used;
      pCost->plan.nRow = nRow;
      pCost->plan.wsFlags = (wsFlags&wsFlagMask);
      pCost->plan.nEq = nEq;
      pCost->plan.u.pIdx = pProbe;
    }

    /* If there was an INDEXED BY or NOT INDEXED clause, only one index is
    ** considered. */
    if( pSrc->pIndex || pSrc->notIndexed ) break;

    /* Reset masks for the next index in the loop */
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }

  /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
................................................................................
    int nConstraint;             /* Number of constraint terms */
    Index *pIdx;                 /* The index we will be using */
    int iIdxCur;                 /* The VDBE cursor for the index */
    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff;               /* Affinity for end of range constraint */
    int regEndKey;               /* Register for end-key */

    pIdx = pLevel->plan.u.pIdx;
    iIdxCur = pLevel->iIdxCur;
    k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]);

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
................................................................................
    testcase( op==OP_Last );
    testcase( op==OP_SeekGt );
    testcase( op==OP_SeekGe );
    testcase( op==OP_SeekLe );
    testcase( op==OP_SeekLt );
    sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);

    /* Set variable op to the instruction required to determine if the
    ** cursor is passed the end of the range. If the range is unbounded,
    ** then set op to OP_Noop. Nothing to do in this case.  */
    op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
    testcase( op==OP_Noop );
    testcase( op==OP_IdxGE );
    testcase( op==OP_IdxLT );
    if( op!=OP_Noop ){

      /* If there is an inequality at the end of this range, compute its
      ** value here.  */
      nConstraint = nEq;
      if( pRangeEnd ){
        Expr *pRight = pRangeEnd->pExpr->pRight;
        sqlite4ExprCacheRemove(pParse, regBase+nEq, 1);
        sqlite4ExprCode(pParse, pRight, regBase+nEq);
        if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
          sqlite4ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
        }
        if( zEndAff ){
          if( sqlite4CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){
            /* Since the comparison is to be performed with no conversions
             ** applied to the operands, set the affinity to apply to pRight to 
             ** SQLITE_AFF_NONE.  */
            zEndAff[nEq] = SQLITE_AFF_NONE;
          }
          if( sqlite4ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
            zEndAff[nEq] = SQLITE_AFF_NONE;
          }
        }  
        codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
        nConstraint++;
        testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      }

      /* Now compute an end-key using OP_MakeKey */
      regEndKey = ++pParse->nMem;
      sqlite4VdbeAddOp2(v, OP_MakeKey, iIdxCur, regEndKey);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nConstraint, 0);
    }

    sqlite4DbFree(pParse->db, zStartAff);
    sqlite4DbFree(pParse->db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);






    if( op!=OP_Noop ){
      /* XXX */
      sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regEndKey, nConstraint);
      sqlite4VdbeChangeP5(v, endEq!=bRev ?1:0);
    }

    /* If there are inequality constraints, check that the value
    ** of the table column that the inequality contrains is not NULL.
    ** If it is, jump to the next iteration of the loop.
    */
................................................................................
      sqlite4VdbeAddOp2(v, OP_IsNull, r1, addrCont);
    }
    sqlite4ReleaseTempReg(pParse, r1);

    /* Seek the table cursor, if required */
    disableTerm(pLevel, pRangeStart);
    disableTerm(pLevel, pRangeEnd);
    if( pIdx->eIndexType!=SQLITE_INDEX_PRIMARYKEY ){
      assert( 0 );
      iRowidReg = iReleaseReg = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
      sqlite4ExprCacheStore(pParse, iCur, -1, iRowidReg);
      sqlite4VdbeAddOp2(v, OP_Seek, iCur, iRowidReg);  /* Deferred seek */
    }

    /* Record the instruction used to terminate the loop. Disable 
................................................................................
      pLevel->op = OP_Noop;
    }else if( bRev ){
      pLevel->op = OP_Prev;
    }else{
      pLevel->op = OP_Next;
    }
    pLevel->p1 = iIdxCur;

  }else

#ifndef SQLITE_OMIT_OR_OPTIMIZATION
  if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
    /* Case 4:  Two or more separately indexed terms connected by OR
    **
    ** Example:
................................................................................
      int iCur = pTabItem->iCursor;
      sqlite4VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
         && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
      int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
      sqlite4OpenPrimaryKey(pParse, pTabItem->iCursor, iDb, pTab, op);
      testcase( pTab->nCol==BMS-1 );
      testcase( pTab->nCol==BMS );
#if 0
      if( !pWInfo->okOnePass && pTab->nCol<BMS ){
        Bitmask b = pTabItem->colUsed;
        int n = 0;
        for(; b; b=b>>1, n++){}
        sqlite4VdbeChangeP4(v, sqlite4VdbeCurrentAddr(v)-1, 
                            SQLITE_INT_TO_PTR(n), P4_INT32);
        assert( n<=pTab->nCol );
      }
#endif
    }else{
      sqlite4TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
      constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
      Index *pIx = pLevel->plan.u.pIdx;
      if( pIx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){
        pLevel->iIdxCur = pTabItem->iCursor;
      }else{
        KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIx);
        int iIdxCur = pLevel->iIdxCur;
        assert( pIx->pSchema==pTab->pSchema );
        assert( iIdxCur>=0 );
        sqlite4VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
            (char*)pKey, P4_KEYINFO_HANDOFF);
        VdbeComment((v, "%s", pIx->zName));
      }
    }
    sqlite4CodeVerifySchema(pParse, iDb);
    notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor);
  }
  pWInfo->iTop = sqlite4VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;

................................................................................
     && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
    ){
      int ws = pLevel->plan.wsFlags;
      if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
        sqlite4VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
      }
      if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){
        if( pLevel->iIdxCur!=pTabItem->iCursor ){
          sqlite4VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
        }
      }
    }

    /* If this scan uses an index, make code substitutions to read data
    ** from the index in preference to the table. Sometimes, this means
    ** the table need never be read from. This is a performance boost,
    ** as the vdbe level waits until the table is read before actually

Added test/simple.test.





















































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# 2012 April 02
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# The tests in this file were used while developing the SQLite 4 code. 
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix simple

#set sqlite_where_trace 1

do_execsql_test 1.0 { 
  PRAGMA table_info = sqlite_master
} {
    0 type text        0 {} 0 
    1 name text        0 {} 0 
    2 tbl_name text    0 {} 0 
    3 rootpage integer 0 {} 0 
    4 sql text         0 {} 0 
}

do_execsql_test 1.1 { SELECT * FROM sqlite_master } {}

#explain { CREATE TABLE t1(a, b) }
#execsql { PRAGMA kv_trace = 1 }
#execsql { PRAGMA vdbe_trace = 1 }

do_execsql_test 1.2 { 
  CREATE TABLE t1(a, b);
  PRAGMA table_info = t1;
} {
    0 a {} 0 {} 0 
    1 b {} 0 {} 0 
}

do_execsql_test 1.3 { 
  CREATE TABLE t2(x, y);
  PRAGMA table_info = t2;
} {
    0 x {} 0 {} 0 
    1 y {} 0 {} 0 
}

do_execsql_test 1.4 { 
  CREATE TABLE t3(k PRIMARY KEY, v);
  PRAGMA table_info = t3;
} {
    0 k {} 0 {} 1 
    1 v {} 0 {} 0 
}

do_execsql_test 1.5 { 
  SELECT name, rootpage FROM sqlite_master 
} {t1 2 t2 3 t3 4}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 2.1 { 
  CREATE TABLE t1(k PRIMARY KEY, v);
  CREATE TABLE t2(x, y); 
} {}

do_execsql_test 2.2.1 { INSERT INTO t1 VALUES('a', 'AAA') }
do_execsql_test 2.2.2 { SELECT * FROM t1 } {a AAA}
do_execsql_test 2.2.3 { INSERT INTO t1 VALUES('b', 'BBB') }
do_execsql_test 2.2.4 { SELECT * FROM t1 } {a AAA b BBB}

do_execsql_test 2.3.1 { INSERT INTO t2 VALUES('123', '456') }
do_execsql_test 2.3.2 { SELECT * FROM t2 } {123 456}
do_execsql_test 2.3.3 { INSERT INTO t2 VALUES('789', '0ab') }
do_execsql_test 2.3.4 { SELECT * FROM t2 } {123 456 789 0ab}

do_catchsql_test 2.2.5 {
  INSERT INTO t1 VALUES('a', 'CCC')
} {1 {column k is not unique}}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 3.1 { CREATE TABLE t1(k PRIMARY KEY, v UNIQUE) }

do_execsql_test 3.2 { 
  SELECT * FROM sqlite_master
} {
  table t1                    t1 2 {CREATE TABLE t1(k PRIMARY KEY, v UNIQUE)} 
  index sqlite_autoindex_t1_2 t1 3 {}
}

#explain { INSERT INTO t1 VALUES('one', '111') }
#execsql { PRAGMA vdbe_trace = 1 }
#execsql { PRAGMA kv_trace = 1 }
#
do_execsql_test 3.3 { INSERT INTO t1 VALUES('one', '111') } {}


#-------------------------------------------------------------------------
reset_db

do_execsql_test 4.1 { CREATE TABLE t1(k PRIMARY KEY, v) }
do_execsql_test 4.2 { CREATE INDEX i1 ON t1(v) }

do_execsql_test 4.3 { 
  SELECT * FROM sqlite_master
} {
  table t1 t1 2 {CREATE TABLE t1(k PRIMARY KEY, v)} 
  index i1 t1 3 {CREATE INDEX i1 ON t1(v)}
}
do_execsql_test 4.4 { INSERT INTO t1 VALUES('one', '111') } {}
do_execsql_test 4.5 { SELECT * FROM t1 } {one 111} 

do_execsql_test 4.6 { PRAGMA integrity_check } {ok}


#-------------------------------------------------------------------------
reset_db

do_execsql_test 5.1 { CREATE TABLE t1(k, v UNIQUE) }
do_execsql_test 5.2 { CREATE INDEX i1 ON t1(v) }

do_execsql_test 5.3 { 
  SELECT * FROM sqlite_master
} {
  table t1                    t1 3 {CREATE TABLE t1(k, v UNIQUE)} 
  index sqlite_autoindex_t1_1 t1 2 {}
  index i1                    t1 4 {CREATE INDEX i1 ON t1(v)}
}

do_execsql_test 5.3 { INSERT INTO t1 VALUES('one', '111') } {}
do_execsql_test 5.4 { SELECT * FROM t1 } {one 111} 
do_execsql_test 5.5 { PRAGMA integrity_check } {ok}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 6.1 { 
  CREATE TABLE t1(k PRIMARY KEY, v);
  CREATE INDEX i1 ON t1(v);
  INSERT INTO t1 VALUES('one', 1);
  INSERT INTO t1 VALUES('two', 2);
  INSERT INTO t1 VALUES('three', 3);
  INSERT INTO t1 VALUES('four', 4);
  INSERT INTO t1 VALUES('five', 5);
}

do_execsql_test 6.2 { 
  SELECT * FROM t1
} {five 5 four 4 one 1 three 3 two 2}

do_execsql_test 6.3 { 
  CREATE TABLE t2(x PRIMARY KEY, y);
  INSERT INTO t2 SELECT v, k FROM t1;
  SELECT * FROM t2
} {1 one 2 two 3 three 4 four 5 five}
do_execsql_test 6.4 { PRAGMA integrity_check } {ok}

do_execsql_test 6.5 { 
  CREATE TABLE t3(a, b);
  INSERT INTO t3 SELECT k, v FROM t1;
  SELECT * FROM t3
} {five 5 four 4 one 1 three 3 two 2}

do_execsql_test 6.6 { 
  INSERT INTO t3 SELECT a, b FROM t3;
  SELECT * FROM t3;
} {five 5 four 4 one 1 three 3 two 2 five 5 four 4 one 1 three 3 two 2}

do_execsql_test 6.7 { PRAGMA integrity_check } {ok}
do_execsql_test 6.8 { CREATE INDEX i2 ON t3(a) }
do_execsql_test 6.9 { PRAGMA integrity_check } {ok}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 7.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(a);
}
do_execsql_test 7.2.1 { INSERT INTO t1 VALUES('xyz', '123') }
do_execsql_test 7.2.2 { INSERT INTO t1 VALUES('xyz', '123') }
do_execsql_test 7.2.3 { INSERT INTO t1 VALUES('xyz', '123') }

do_execsql_test 7.3 {
  SELECT * FROM t1;
} {xyz 123 xyz 123 xyz 123}

do_execsql_test 7.4 { PRAGMA integrity_check } {ok}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 8.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES('a', 'b');
}

do_execsql_test 8.2 { DELETE FROM t1 WHERE b = 'b' }
do_execsql_test 8.3 { SELECT * FROM t1 } {}
do_execsql_test 8.4 {
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'B');
  INSERT INTO t1 VALUES('c', 'A');
  INSERT INTO t1 VALUES('d', 'B');
  INSERT INTO t1 VALUES('e', 'A');
  INSERT INTO t1 VALUES('f', 'B');
}
do_execsql_test 8.5 { DELETE FROM t1 WHERE b = 'B' }
do_execsql_test 8.6 { SELECT * FROM t1 } {a A c A e A}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 9.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(b);
}

do_execsql_test 9.2 {
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'B');
  INSERT INTO t1 VALUES('c', 'A');
  INSERT INTO t1 VALUES('d', 'B');
  INSERT INTO t1 VALUES('e', 'A');
  INSERT INTO t1 VALUES('f', 'B');
}
do_execsql_test 9.3 { DELETE FROM t1 WHERE +b = 'B' }
do_execsql_test 9.4 { SELECT * FROM t1 } {a A c A e A}
do_execsql_test 9.5 { PRAGMA integrity_check } {ok}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 10.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(b);
}
do_execsql_test 10.2 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
}

# explain { UPDATE t1 SET b = 10 WHERE a=3 }
#  execsql { PRAGMA vdbe_trace = 1 }

do_execsql_test 10.3 { 
  UPDATE t1 SET b = 10 WHERE a=3;
  SELECT * FROM t1;
} {1 2 3 10}

do_execsql_test 10.4 { PRAGMA integrity_check } {ok}
execsql { PRAGMA kvdump }

finish_test

#proc populate_t1 {} {
#  db eval {
#    INSERT INTO t1(a, b) VALUES(4, 'four');
#    INSERT INTO t1(a, b) VALUES(9, 'nine');
#    INSERT INTO t1(a, b) VALUES(5, 'five');
#    INSERT INTO t1(a, b) VALUES(1, 'one');
#    INSERT INTO t1(a, b) VALUES(7, 'seven');
#    INSERT INTO t1(a, b) VALUES(8, 'eight');
#    INSERT INTO t1(a, b) VALUES(2, 'two');
#    INSERT INTO t1(a, b) VALUES(3, 'three');
#    INSERT INTO t1(a, b) VALUES(6, 'six');
#    INSERT INTO t1(a, b) VALUES(10, 'ten');
#  }
#}
#
#foreach {t schema} {
#  1 "CREATE TABLE t1(a, b)"
#  2 "CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a);"
#  3 "CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(b);"
#  4 "CREATE TABLE t1(a PRIMARY KEY, b)"
#} {
#
#  do_test 1.$t.0 {
#    reset_db
#    execsql $schema
#    populate_t1
#  } {}
#
#  foreach {u sql res} {
#    1 "SELECT * FROM t1 WHERE a = 7"        {7 seven}
#    2 "SELECT * FROM t1 WHERE b = 'seven'"  {7 seven}
#  } {
#    do_execsql_test 1.$t.$u $sql $res
#  }
#}

finish_test

Changes to test/tester.tcl.

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# Set the precision of FP arithmatic used by the interpreter. And 
# configure SQLite to take database file locks on the page that begins
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#
set tcl_precision 15
sqlite4_test_control_pending_byte 0x0010000


# If the pager codec is available, create a wrapper for the [sqlite4] 
# command that appends "-key {xyzzy}" to the command line. i.e. this:
#
#     sqlite4 db test.db
#
................................................................................

  # Install the malloc layer used to inject OOM errors. And the 'automatic'
  # extensions. This only needs to be done once for the process.
  #
  sqlite4_shutdown 
  install_malloc_faultsim 1 
  sqlite4_initialize
  autoinstall_test_functions

  # If the --binarylog option was specified, create the logging VFS. This
  # call installs the new VFS as the default for all SQLite connections.
  #
  if {$cmdlinearg(binarylog)} {
    vfslog new binarylog {} vfslog.bin
  }
................................................................................

  set omitList [set_test_counter omit_list]

  catch {db close}
  catch {db2 close}
  catch {db3 close}

  vfs_unlink_test
  sqlite4 db {}
  # sqlite4_clear_tsd_memdebug
  db close
  sqlite4_reset_auto_extension

  sqlite4_soft_heap_limit 0
  set nTest [incr_ntest]
  set nErr [set_test_counter errors]

  puts "$nErr errors out of $nTest tests"
  if {$nErr>0} {







|







 







|







 







|



|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# Set the precision of FP arithmatic used by the interpreter. And 
# configure SQLite to take database file locks on the page that begins
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#
set tcl_precision 15
#sqlite4_test_control_pending_byte 0x0010000


# If the pager codec is available, create a wrapper for the [sqlite4] 
# command that appends "-key {xyzzy}" to the command line. i.e. this:
#
#     sqlite4 db test.db
#
................................................................................

  # Install the malloc layer used to inject OOM errors. And the 'automatic'
  # extensions. This only needs to be done once for the process.
  #
  sqlite4_shutdown 
  install_malloc_faultsim 1 
  sqlite4_initialize
  #autoinstall_test_functions

  # If the --binarylog option was specified, create the logging VFS. This
  # call installs the new VFS as the default for all SQLite connections.
  #
  if {$cmdlinearg(binarylog)} {
    vfslog new binarylog {} vfslog.bin
  }
................................................................................

  set omitList [set_test_counter omit_list]

  catch {db close}
  catch {db2 close}
  catch {db3 close}

  #vfs_unlink_test
  sqlite4 db {}
  # sqlite4_clear_tsd_memdebug
  db close
  #sqlite4_reset_auto_extension

  sqlite4_soft_heap_limit 0
  set nTest [incr_ntest]
  set nErr [set_test_counter errors]

  puts "$nErr errors out of $nTest tests"
  if {$nErr>0} {