SQLite4
Changes On Branch primary-keys
Not logged in

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

Changes In Branch primary-keys Excluding Merge-Ins

This is equivalent to a diff from a03018e6b8 to 49e419f4e8

2012-04-20
20:41
Move development back to trunk. check-in: 76ca8d1bee user: drh tags: trunk
20:38
Changes so that things work without SQLITE_ENABLE_LSM. Closed-Leaf check-in: 49e419f4e8 user: dan tags: primary-keys
20:15
Fix the sqlite4RefillIndex() function. This removes the broken (and disabled) merge-sort code. check-in: 9ac54fff5f 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
2012-02-23
17:56
Modify the key encoding so that integer values use one less byte of space. check-in: af96bd359f user: drh tags: trunk

Changes to main.mk.

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
89
90
91
92
93
94
95

96
97
98
99
100
101
102
...
209
210
211
212
213
214
215

216
217
218
219
220
221
222
...
456
457
458
459
460
461
462





463
464
465
466

467
468
469
470
471
472
473
#
LIBOBJ+= alter.o analyze.o attach.o auth.o \
         bitvec.o build.o \
         callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
         fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
         fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
         fts3_write.o func.o global.o hash.o \
         icu.o insert.o kvmem.o legacy.o \
         main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o os_os2.o os_unix.o os_win.o \
         parse.o pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o storage.o \
         table.o tokenize.o trigger.o \
         update.o util.o varint.o \
................................................................................
  $(TOP)/src/fkey.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \

  $(TOP)/src/kvmem.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/math.c \
  $(TOP)/src/mem0.c \
  $(TOP)/src/mem1.c \
................................................................................
  $(TOP)/src/test_malloc.c \
  $(TOP)/src/test_mutex.c \
  $(TOP)/src/test_onefile.c \
  $(TOP)/src/test_osinst.c \
  $(TOP)/src/test_rtree.c \
  $(TOP)/src/test_schema.c \
  $(TOP)/src/test_storage.c \

  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/test_thread.c \
  $(TOP)/src/test_vfs.c \
  $(TOP)/src/test_wholenumber.c \
  $(TOP)/src/test_wsd.c

#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
................................................................................
		$(TOP)/src/tclsqlite.c libsqlite4.a $(LIBTCL) $(THREADLIB)

# Rules to build the 'testfixture' application.
#
TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 






testfixture$(EXE): $(TESTSRC2) libsqlite4.a $(TESTSRC) $(TOP)/src/tclsqlite.c
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite4.a


amalgamation-testfixture$(EXE): sqlite4.c $(TESTSRC) $(TOP)/src/tclsqlite.c
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite4.c                  \
		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)

fts3-testfixture$(EXE): sqlite4.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c







|







 







>







 







>







 







>
>
>
>
>
|


|
>







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
#
LIBOBJ+= alter.o analyze.o attach.o auth.o \
         bitvec.o build.o \
         callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
         fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
         fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
         fts3_write.o func.o global.o hash.o \
         icu.o insert.o kvlsm.o kvmem.o legacy.o \
         main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o os_os2.o os_unix.o os_win.o \
         parse.o pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o storage.o \
         table.o tokenize.o trigger.o \
         update.o util.o varint.o \
................................................................................
  $(TOP)/src/fkey.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/kvlsm.c \
  $(TOP)/src/kvmem.c \
  $(TOP)/src/legacy.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/math.c \
  $(TOP)/src/mem0.c \
  $(TOP)/src/mem1.c \
................................................................................
  $(TOP)/src/test_malloc.c \
  $(TOP)/src/test_mutex.c \
  $(TOP)/src/test_onefile.c \
  $(TOP)/src/test_osinst.c \
  $(TOP)/src/test_rtree.c \
  $(TOP)/src/test_schema.c \
  $(TOP)/src/test_storage.c \
  $(TOP)/src/test_storage2.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/test_thread.c \
  $(TOP)/src/test_vfs.c \
  $(TOP)/src/test_wholenumber.c \
  $(TOP)/src/test_wsd.c

#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
................................................................................
		$(TOP)/src/tclsqlite.c libsqlite4.a $(LIBTCL) $(THREADLIB)

# Rules to build the 'testfixture' application.
#
TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 

TESTFIXTURE_PREREQ  = $(TESTSRC) $(TESTSRC2) 
TESTFIXTURE_PREREQ += $(TOP)/src/tclsqlite.c
TESTFIXTURE_PREREQ += libsqlite4.a
TESTFIXTURE_PREREQ += $(LIBEXTRA)

testfixture$(EXE): $(TESTFIXTURE_PREREQ)
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite4.a     \
		$(LIBEXTRA)

amalgamation-testfixture$(EXE): sqlite4.c $(TESTSRC) $(TOP)/src/tclsqlite.c
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite4.c                  \
		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)

fts3-testfixture$(EXE): sqlite4.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c

Changes to src/auth.c.

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  }
  iCol = pExpr->iColumn;
  if( NEVER(pTab==0) ) return;

  if( iCol>=0 ){
    assert( iCol<pTab->nCol );
    zCol = pTab->aCol[iCol].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( iDb>=0 && iDb<db->nDb );
  if( SQLITE_IGNORE==sqlite4AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
    pExpr->op = TK_NULL;
  }







<
<
<







166
167
168
169
170
171
172



173
174
175
176
177
178
179
  }
  iCol = pExpr->iColumn;
  if( NEVER(pTab==0) ) return;

  if( iCol>=0 ){
    assert( iCol<pTab->nCol );
    zCol = pTab->aCol[iCol].zName;



  }else{
    zCol = "ROWID";
  }
  assert( iDb>=0 && iDb<db->nDb );
  if( SQLITE_IGNORE==sqlite4AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
    pExpr->op = TK_NULL;
  }

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
...
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
...
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
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
....
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
....
1841
1842
1843
1844
1845
1846
1847

1848

1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
....
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
2254
2255
2256
2257
2258
2259


2260
2261
2262
2263
2264
2265
2266
2267
2268


2269
2270
2271
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300

2301
2302

2303
2304
2305
2306
2307
2308
2309

2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
....
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
................................................................................
  if( pTable==0 ){
    db->mallocFailed = 1;
    pParse->rc = SQLITE_NOMEM;
    pParse->nErr++;
    goto begin_table_error;
  }
  pTable->zName = zName;
  pTable->iPKey = -1;
  pTable->pSchema = db->aDb[iDb].pSchema;
  pTable->nRef = 1;
  pTable->nRowEst = 1000000;
  assert( pParse->pNewTable==0 );
  pParse->pNewTable = pTable;

  /* If this is the magic sqlite_sequence table used by autoincrement,
................................................................................
  ** 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;
  }
  pTab->tabFlags |= TF_HasPrimaryKey;
  if( pList==0 ){
    iCol = pTab->nCol - 1;
    pTab->aCol[iCol].isPrimKey = 1;

  }else{
    for(i=0; i<pList->nExpr; i++){
      for(iCol=0; iCol<pTab->nCol; iCol++){
        if( sqlite4StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      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
................................................................................
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite4GetVdbe(pParse);
  sqlite4VdbeAddOp2(v, OP_Clear, iTable, iDb);

  sqlite4MayAbort(pParse);

}

/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** 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))
................................................................................
}

/*
** Generate code that will erase and refill index *pIdx.  This is
** used to initialize a newly created index or to recompute the
** content of an index in response to a REINDEX command.
*/
static void sqlite4RefillIndex(Parse *pParse, Index *pIndex){
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab++;     /* Cursor used for pTab */
  int iIdx = pParse->nTab++;     /* Cursor used for pIndex */
  int iSorter;                   /* Cursor opened by OpenSorter (if in use) */
  int addr1;                     /* Address of top of loop */
  int addr2;                     /* Address to jump to for next iteration */
  int tnum;                      /* Root page of index */
  Vdbe *v;                       /* Generate code into this virtual machine */
  KeyInfo *pKey;                 /* KeyInfo for index */
#ifdef SQLITE_OMIT_MERGE_SORT
  int regIdxKey;                 /* Registers containing the index key */
#endif
  int regRecord;                 /* Register holding assemblied index record */
  sqlite4 *db = pParse->db;      /* The database connection */
  int iDb = sqlite4SchemaToIndex(db, pIndex->pSchema);


#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite4AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
      db->aDb[iDb].zName ) ){
    return;
  }
#endif

  /* Require a write-lock on the table to perform this operation */
  sqlite4TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);

  v = sqlite4GetVdbe(pParse);
  if( v==0 ) return;


  tnum = pIndex->tnum;
  sqlite4VdbeAddOp2(v, OP_Clear, tnum, iDb);
  pKey = sqlite4IndexKeyinfo(pParse, pIndex);
  sqlite4VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
                    (char *)pKey, P4_KEYINFO_HANDOFF);



#ifndef SQLITE_OMIT_MERGE_SORT
  /* Open the sorter cursor if we are to use one. */
  iSorter = pParse->nTab++;
  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);
  sqlite4VdbeJumpHere(v, addr1);
  addr1 = sqlite4VdbeAddOp2(v, OP_SorterSort, iSorter, 0);


  if( pIndex->onError!=OE_None ){
    int j2 = sqlite4VdbeCurrentAddr(v) + 3;
    sqlite4VdbeAddOp2(v, OP_Goto, 0, j2);
    addr2 = sqlite4VdbeCurrentAddr(v);
    sqlite4VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
    sqlite4HaltConstraint(
        pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
    );
  }else{
    addr2 = sqlite4VdbeCurrentAddr(v);

  }
  sqlite4VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
  sqlite4VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);  ***** busted
  sqlite4VdbeChangeP5(v, OPFLAG_USESEEKRESULT | OPFLAG_APPENDBIAS);
#else
  regIdxKey = sqlite4GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, iIdx);
  addr2 = addr1 + 1;
  if( pIndex->onError!=OE_None ){
    const int regRowid = regIdxKey + pIndex->nColumn;
    const int j2 = sqlite4VdbeCurrentAddr(v) + 2;
    void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);

    /* The registers accessed by the OP_IsUnique opcode were allocated
    ** using sqlite4GetTempRange() inside of the sqlite4GenerateIndexKey()
    ** call above. Just before that function was freed they were released
    ** (made available to the compiler for reuse) using 
    ** sqlite4ReleaseTempRange(). So in some ways having the OP_IsUnique
    ** opcode use the values stored within seems dangerous. However, since
    ** we can be sure that no other temp registers have been allocated
    ** since sqlite4ReleaseTempRange() was called, it is safe to do so.
    */
    sqlite4VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);

    sqlite4HaltConstraint(
        pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);

  }
  sqlite4VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, regRecord+1);
  sqlite4VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
#endif
  sqlite4ReleaseTempRange(pParse, regRecord, 2);
  sqlite4VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
  sqlite4VdbeJumpHere(v, addr1);


  sqlite4VdbeAddOp1(v, OP_Close, iTab);
  sqlite4VdbeAddOp1(v, OP_Close, iIdx);
  sqlite4VdbeAddOp1(v, OP_Close, iSorter);
}

/*
** Create a new index for an SQL table.  pName1.pName2 is the name of the index 
** and pTblList is the name of the table that is to be indexed.  Both will 
** be NULL for a primary key or an index that is created to satisfy a
** UNIQUE constraint.  If pTable and pIndex are NULL, use pParse->pNewTable
................................................................................
  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
...
841
842
843
844
845
846
847

848
849
850
851
852
853
854
...
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
...
885
886
887
888
889
890
891

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
....
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
....
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
....
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
....
1608
1609
1610
1611
1612
1613
1614










1615
1616
1617
1618
1619
1620
1621
....
1659
1660
1661
1662
1663
1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
....
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
....
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980

1981
1982
1983
1984
1985
1986
1987
....
2327
2328
2329
2330
2331
2332
2333
2334
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
2366
2367
2368





2369



2370
2371
2372
2373







2374
2375
2376





2377



2378
2379





















2380
2381

2382
2383
2384



2385
2386
2387
2388
2389
2390

2391
2392
2393
2394
2395
2396
2397
....
2412
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
2440
2441
....
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
....
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
....
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
....
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568

2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
....
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
....
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
....
2751
2752
2753
2754
2755
2756
2757









2758
2759
2760
2761
2762
2763
2764
2765
2766
....
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787

2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
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
....
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
....
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
....
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
3741
3742
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
  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
................................................................................
  if( pTable==0 ){
    db->mallocFailed = 1;
    pParse->rc = SQLITE_NOMEM;
    pParse->nErr++;
    goto begin_table_error;
  }
  pTable->zName = zName;

  pTable->pSchema = db->aDb[iDb].pSchema;
  pTable->nRef = 1;
  pTable->nRowEst = 1000000;
  assert( pParse->pNewTable==0 );
  pParse->pNewTable = pTable;

  /* If this is the magic sqlite_sequence table used by autoincrement,
................................................................................
  ** 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;
  }
  pTab->tabFlags |= TF_HasPrimaryKey;
  if( pList==0 ){
    iCol = pTab->nCol - 1;
    pTab->aCol[iCol].isPrimKey = 1;
    pTab->aCol[iCol].notNull = 1;
  }else{
    for(i=0; i<pList->nExpr; i++){
      for(iCol=0; iCol<pTab->nCol; iCol++){
        if( sqlite4StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = 1;
        pTab->aCol[iCol].notNull = 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 */

  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( !IsView(p) ){
    Index *pPk;                   /* PRIMARY KEY index of table p */
    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
................................................................................
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite4GetVdbe(pParse);
  sqlite4VdbeAddOp2(v, OP_Clear, iTable, iDb);
#if 0
  sqlite4MayAbort(pParse);
#endif
}

/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** 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))
................................................................................
}

/*
** Generate code that will erase and refill index *pIdx.  This is
** used to initialize a newly created index or to recompute the
** content of an index in response to a REINDEX command.
*/
static void sqlite4RefillIndex(Parse *pParse, Index *pIdx){
  Table *pTab = pIdx->pTable;    /* The table that is indexed */
  int iTab = pParse->nTab++;     /* Cursor used for PK of pTab */
  int iIdx = pParse->nTab++;     /* Cursor used for pIdx */
  int iSorter;                   /* Cursor opened by OpenSorter (if in use) */
  int addr1;                     /* Address of top of loop */
  int addr2;                     /* Address to jump to for next iteration */
  int tnum;                      /* Root page of index */
  Vdbe *v;                       /* Generate code into this virtual machine */


  int regKey;                    /* Registers containing the index key */

  int regRecord;                 /* Register holding assemblied index record */
  sqlite4 *db = pParse->db;      /* The database connection */
  int iDb = sqlite4SchemaToIndex(db, pIdx->pSchema);
  Index *pPk;

#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite4AuthCheck(pParse, SQLITE_REINDEX, pIdx->zName, 0,
      db->aDb[iDb].zName ) ){
    return;
  }
#endif

  pPk = sqlite4FindPrimaryKey(pTab, 0);


  v = sqlite4GetVdbe(pParse);
  if( v==0 ) return;

  /* A write-lock on the table is required to perform this operation. Easiest
  ** way to do this is to open a write-cursor on the PK - even though this
  ** operation only requires read access.  */
  sqlite4OpenPrimaryKey(pParse, iTab, iDb, pTab, OP_OpenWrite);



  /* Delete the current contents (if any) of the index. Then open a write
  ** cursor on it.  */
  sqlite4VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
  sqlite4OpenIndex(pParse, iIdx, iDb, pIdx, OP_OpenWrite);









  /* Loop through the contents of the PK index. At each row, insert the
  ** corresponding entry into the auxiliary index.  */
  addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);
  regRecord = sqlite4GetTempRange(pParse,2);







  regKey = sqlite4GetTempReg(pParse);
  sqlite4EncodeIndexKey(pParse, pPk, iTab, pIdx, iIdx, regKey);
  if( pIdx->onError!=OE_None ){





    const char *zErr = "indexed columns are not unique";



    int addrTest;
     





















    addrTest = sqlite4VdbeAddOp4Int(v, OP_IsUnique, iIdx, 0, regKey, 0);
    sqlite4HaltConstraint(pParse, OE_Abort, zErr, P4_STATIC);

    sqlite4VdbeJumpHere(v, addrTest);
  }
  sqlite4VdbeAddOp3(v, OP_IdxInsert, iIdx, 0, regKey);  



  sqlite4VdbeAddOp2(v, OP_Next, iTab, addr1+1);
  sqlite4VdbeJumpHere(v, addr1);
  sqlite4ReleaseTempReg(pParse, regKey);

  sqlite4VdbeAddOp1(v, OP_Close, iTab);
  sqlite4VdbeAddOp1(v, OP_Close, iIdx);

}

/*
** Create a new index for an SQL table.  pName1.pName2 is the name of the index 
** and pTblList is the name of the table that is to be indexed.  Both will 
** be NULL for a primary key or an index that is created to satisfy a
** UNIQUE constraint.  If pTable and pIndex are NULL, use pParse->pNewTable
................................................................................
  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.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
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
299
300



301
302
303
304
305
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
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
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
...
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
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
...
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
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
** return a pointer.  Set an error message and return NULL if the table 
** name is not found or if any other error occurs.
**
** The following fields are initialized appropriate in pSrc:
**
**    pSrc->a[0].pTab       Pointer to the Table object
**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one
**
*/
Table *sqlite4SrcListLookup(Parse *pParse, SrcList *pSrc){
  struct SrcList_item *pItem = pSrc->a;
  Table *pTab;
  assert( pItem && pSrc->nSrc==1 );
  pTab = sqlite4LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
  sqlite4DeleteTable(pParse->db, pItem->pTab);
................................................................................
**                  pTabList              pWhere
*/
void sqlite4DeleteFrom(
  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 */
  int iDb;               /* Database number */
  int memCnt = -1;       /* Memory cell used for change counting */
  int rcauth;            /* Value returned by authorization callback */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */

  Trigger *pTrigger;           /* List of table triggers, if required */
#endif

  memset(&sContext, 0, sizeof(sContext));


  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    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
  */
  if( isView ){
    sqlite4AuthContextPush(pParse, &sContext, pTab->zName);
  }

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

  /* If we are trying to delete from a view, realize that view into
  ** a ephemeral table.
  */

#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
  if( isView ){
    sqlite4MaterializeView(pParse, pTab, pWhere, iCur);
  }
#endif

  /* Resolve the column names in the WHERE clause.
  */
  memset(&sNC, 0, sizeof(sNC));

  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;
  if( sqlite4ResolveExprNames(&sNC, pWhere) ){
    goto delete_from_cleanup;
  }

  /* Initialize the counter of the number of rows deleted, if
  ** we are counting rows.
  */
  if( db->flags & SQLITE_CountRows ){
    memCnt = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, memCnt);
  }

#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.
  ** 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 ){
    sqlite4AutoincrementEnd(pParse);
  }

  /* Return the number of rows that were deleted. If this routine is 
  ** generating code because of a call to sqlite4NestedParse(), do not
  ** invoke the callback function.
  */
  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
    sqlite4VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
    sqlite4VdbeSetNumCols(v, 1);
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
  }

delete_from_cleanup:
  sqlite4AuthContextPop(&sContext);
  sqlite4SrcListDelete(db, pTabList);
  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).  */
#ifdef isView
 #undef isView
#endif
#ifdef pTrigger
 #undef pTrigger
#endif

/*
** This routine generates VDBE code that causes a single row of a
** single table to be deleted.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
................................................................................
**   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(
        pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf
    );
    mask |= sqlite4FkOldmask(pParse, pTab);







    iOld = pParse->nMem+1;
    pParse->nMem += (1 + pTab->nCol);

    /* Populate the OLD.* pseudo-table register array. These values will be 
    ** used by any BEFORE and AFTER triggers that exist.  */
    sqlite4VdbeAddOp2(v, OP_Copy, iRowid, iOld);
    for(iCol=0; iCol<pTab->nCol; iCol++){
      if( mask==0xffffffff || mask&(1<<iCol) ){
        sqlite4ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, iOld+iCol+1);
      }
    }





    /* Invoke BEFORE DELETE trigger programs. */
    sqlite4CodeRowTrigger(pParse, pTrigger, 
        TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
    );

    /* Seek the cursor to the row to be deleted again. It may be that
    ** the BEFORE triggers coded above have already removed the row
    ** being deleted. Do not attempt to delete the row a second time, and 
    ** do not fire AFTER triggers.  */
    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);

  /* Invoke AFTER DELETE trigger programs. */
  sqlite4CodeRowTrigger(pParse, pTrigger, 
      TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
  );

  /* 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.
................................................................................
  int nCol;

  nCol = pIdx->nColumn;
  regBase = sqlite4GetTempRange(pParse, nCol+1);
  sqlite4VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
  for(j=0; j<nCol; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite4VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
    }else{
      sqlite4VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
      sqlite4ColumnDefault(v, pTab, idx, -1);
    }
  }
  if( doMakeRec ){







<







 







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


>
>






|
|
<
<
<


>
>
>

|
<
<
<

<
<
<
<
<
<
<
<
<

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





<

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

<
|
<




|
<
>
|
<


<

|
<
<
>






<
<
<
<
<
<
<
<






|

|
<
<










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




<
|
<
|
<


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


|












|
|
>



|
|

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








<
<
<
<
<
<
<
<
<







 







|
|
|
|
|
|
|


|

>
>
>




>
>
>
|



|



|



|
|
>
>
>
>
>
>




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


|


>
>
>
>



|






|




|





|
|
<
<
<
<




|
>
|



|







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







 







|
|
|
|

>
>
>

>

<

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







 







|







22
23
24
25
26
27
28

29
30
31
32
33
34
35
...
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
299


300
301
302
303
304
305
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
...
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
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




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
544
545
546
547
548
549
550
551
552
553
554
555
556
...
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
...
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
** return a pointer.  Set an error message and return NULL if the table 
** name is not found or if any other error occurs.
**
** The following fields are initialized appropriate in pSrc:
**
**    pSrc->a[0].pTab       Pointer to the Table object
**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one

*/
Table *sqlite4SrcListLookup(Parse *pParse, SrcList *pSrc){
  struct SrcList_item *pItem = pSrc->a;
  Table *pTab;
  assert( pItem && pSrc->nSrc==1 );
  pTab = sqlite4LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
  sqlite4DeleteTable(pParse->db, pItem->pTab);
................................................................................
**                  pTabList              pWhere
*/
void sqlite4DeleteFrom(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table from which we should delete things */
  Expr *pWhere           /* The WHERE clause.  May be null */
){
  sqlite4 *db = pParse->db;       /* Main database structure */
  Vdbe *v;                        /* The virtual database engine */

  Table *pTab;                    /* Table to delete from */
  const char *zDb;                /* Name of database holding pTab */






  AuthContext sContext;           /* Authorization context */
  NameContext sNC;                /* Name context to resolve WHERE expression */
  int iDb;                        /* Database number */

  int rcauth;                     /* Value returned by authorization callback */



  int iCur;                       /* Cursor number used by where.c */
  Trigger *pTrigger;              /* List of triggers, or NULL */


  memset(&sContext, 0, sizeof(sContext));
  memset(&sNC, 0, sizeof(sNC));

  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    goto delete_from_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete. If it is a view, make sure
  ** that the column names are initialized. */



  pTab = sqlite4SrcListLookup(pParse, pTabList);
  if( pTab==0 )  goto delete_from_cleanup;
  iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;
  assert( iDb<db->nDb );

  /* Figure out if there are any triggers */



  pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);










  /* 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. A table is read-only if it is one
  ** of the built-in system tables (e.g. sqlite_master, sqlite_stat) or
  ** if it is a view and there are no INSTEAD OF triggers to handle the 
  ** delete.  */
  if( sqlite4IsReadOnly(pParse, pTab, pTrigger!=0) ) goto delete_from_cleanup;

  assert( !IsView(pTab) || pTrigger );
  assert( !IsView(pTab) || pTab->pIndex==0 );




  /* Invoke the authorization callback */
  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 a cursor number to the table or view this statement is 
  ** deleting from. If pTab is actually a view, this will be used as the
  ** ephemeral table cursor. 
  **

  ** Or, if this is a real table, it is the number of a read-only cursor 
  ** used by where.c to iterate through those records that match the WHERE 
  ** clause supplied by the user. This is a separate cursor from the array
  ** of read-write cursors used to delete entries from each of the tables
  ** indexes.  */
  pTabList->a[0].iCursor = iCur = pParse->nTab++;








  /* Begin generating code */

  v = sqlite4GetVdbe(pParse);

  if( v==0 ) goto delete_from_cleanup;

  if( pParse->nested==0 ) sqlite4VdbeCountChanges(v);
  sqlite4BeginWriteOperation(pParse, 1, iDb);

  /* If we are trying to delete from a view, realize that view into
  ** a ephemeral table.  */

  if( IsView(pTab) ){
    sqlite4AuthContextPush(pParse, &sContext, pTab->zName);

    sqlite4MaterializeView(pParse, pTab, pWhere, iCur);
  }


  /* Resolve the column names in the WHERE clause. This has to come after


  ** the call to sqlite4MaterializeView() above.  */
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;
  if( sqlite4ResolveExprNames(&sNC, pWhere) ){
    goto delete_from_cleanup;
  }









#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.
  ** 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)
  ){
    Index *pIdx;                  /* For looping over indices of the table */


    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.
  */
  {
    WhereInfo *pWInfo;            /* Information about the WHERE clause */
    int baseCur = 0;
    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);

    sqlite4WhereEnd(pWInfo);






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





    ** from which we are deleting.  */
    if( !IsView(pTab) ){
      baseCur = pParse->nTab;
      sqlite4OpenAllIndexes(pParse, pTab, baseCur, 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
    {
      sqlite4GenerateRowDelete(
          pParse, pTab, baseCur, regKey, pParse->nested==0, pTrigger, OE_Default
      );
    }

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

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























  }

delete_from_cleanup:
  sqlite4AuthContextPop(&sContext);
  sqlite4SrcListDelete(db, pTabList);
  sqlite4ExprDelete(db, pWhere);
  return;
}










/*
** This routine generates VDBE code that causes a single row of a
** single table to be deleted.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
................................................................................
**   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 regOld = 0;                 /* First register in OLD.* array */
  int iLabel;                     /* Label resolved to end of generated code */
  int iPk;                        /* Offset of PK cursor in cursor array */
  int iPkCsr;                     /* Primary key cursor number */
  Index *pPk;                     /* Primary key index */

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

  pPk = sqlite4FindPrimaryKey(pTab, &iPk);
  iPkCsr = baseCur + iPk;

  /* Seek the PK cursor 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);
  sqlite4VdbeAddOp4Int(v, OP_NotFound, iPkCsr, iLabel, regKey, 0);
 
  /* 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) || pTrigger ){
    u32 mask;                     /* Mask of OLD.* columns in use */
    int iCol;                     /* Iterator used while populating OLD.* */

    /* Determine which table columns may be required by either foreign key
    ** logic or triggers. This block sets stack variable mask to a 32-bit mask
    ** where bit 0 corresponds to the left-most table column, bit 1 to the
    ** second left-most, and so on. If an OLD.* column may be required, then
    ** the corresponding bit is set.
    **
    ** Or, if the table contains more than 32 columns and at least one of
    ** the columns following the 32nd is required, set mask to 0xffffffff.  */
    mask = sqlite4TriggerColmask(
        pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf
    );
    mask |= sqlite4FkOldmask(pParse, pTab);

    /* Allocate an array of (nCol+1) registers, where nCol is the number
    ** of columns in the table. 
    **
    ** If the table has an implicit PK, the first register in the array 
    ** contains the rowid. Otherwise, its contents are undefined. The 
    ** remaining registers contain the OLD.* column values, in order. */
    regOld = pParse->nMem+1;
    pParse->nMem += (pTab->nCol+1);




    for(iCol=0; iCol<pTab->nCol; iCol++){
      if( mask==0xffffffff || mask&(1<<iCol) ){
        sqlite4ExprCodeGetColumnOfTable(v, pTab, iPkCsr, iCol, regOld+iCol+1);
      }
    }
    assert( (pPk==0)==IsView(pTab) );
    if( pPk && pPk->aiColumn[0]<0 ){
      sqlite4VdbeAddOp2(v, OP_Rowid, iPkCsr, regOld);
    }

    /* Invoke BEFORE DELETE trigger programs. */
    sqlite4CodeRowTrigger(pParse, pTrigger, 
        TK_DELETE, 0, TRIGGER_BEFORE, pTab, regOld, onconf, iLabel
    );

    /* Seek the cursor to the row to be deleted again. It may be that
    ** the BEFORE triggers coded above have already removed the row
    ** being deleted. Do not attempt to delete the row a second time, and 
    ** do not fire AFTER triggers.  */
    sqlite4VdbeAddOp4Int(v, OP_NotFound, iPkCsr, iLabel, regKey, 0);

    /* 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, regOld+1, 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( !IsView(pTab) ){
    sqlite4GenerateRowIndexDelete(pParse, pTab, baseCur, 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 deleted. This is a no-op if there are no configured
  ** foreign keys that use this table as a parent table.  */ 
  sqlite4FkActions(pParse, pTab, 0, regOld+1);

  /* Invoke AFTER DELETE trigger programs. */
  sqlite4CodeRowTrigger(pParse, pTrigger, 
      TK_DELETE, 0, TRIGGER_AFTER, pTab, regOld, onconf, iLabel
  );

  /* 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);
}

void sqlite4EncodeIndexKey(
  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;
      sqlite4EncodeIndexKey(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.
................................................................................
  int nCol;

  nCol = pIdx->nColumn;
  regBase = sqlite4GetTempRange(pParse, nCol+1);
  sqlite4VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
  for(j=0; j<nCol; j++){
    int idx = pIdx->aiColumn[j];
    if( idx<0 ){
      sqlite4VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
    }else{
      sqlite4VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
      sqlite4ColumnDefault(v, pTab, idx, -1);
    }
  }
  if( doMakeRec ){

Changes to src/expr.c.

1455
1456
1457
1458
1459
1460
1461




1462
1463
1464
1465
1466
1467
1468
....
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
....
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
....
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
....
2723
2724
2725
2726
2727
2728
2729





2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
    sqlite4 *db = pParse->db;              /* Database connection */
    Table *pTab;                           /* Table <table>. */
    Expr *pExpr;                           /* Expression <column> */
    int iCol;                              /* Index of column <column> */
    int iDb;                               /* Database idx for pTab */





    assert( p );                        /* Because of isCandidateForInOpt(p) */
    assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
    assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
    assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
    pTab = p->pSrc->a[0].pTab;
    pExpr = p->pEList->a[0].pExpr;
................................................................................
    sqlite4TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

    /* This function is only called from two places. In both cases the vdbe
    ** has already been allocated. So assume sqlite4GetVdbe() is always
    ** successful here.
    */
    assert(v);
    if( iCol<0 ){
      int iAddr;

      iAddr = sqlite4CodeOnce(pParse);

      sqlite4OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
      eType = IN_INDEX_ROWID;

      sqlite4VdbeJumpHere(v, iAddr);
    }else{
      Index *pIdx;                         /* Iterator variable */

      /* The collation sequence used by the comparison. If an index is to
      ** be used in place of a temp-table, it must be ordered according
      ** to this collation sequence.  */
      CollSeq *pReq = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);

      /* Check that the affinity that will be used to perform the 
      ** comparison is the same as the affinity of the column. If
      ** it is not, it is not possible to use any index.
      */
      char aff = comparisonAffinity(pX);
      int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);

      for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
        if( (pIdx->aiColumn[0]==iCol)
         && sqlite4FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
         && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
        ){
          int iAddr;
          char *pKey;
  
          pKey = (char *)sqlite4IndexKeyinfo(pParse, pIdx);
          iAddr = sqlite4CodeOnce(pParse);
  
          sqlite4VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
                               pKey,P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIdx->zName));
          eType = IN_INDEX_INDEX;

          sqlite4VdbeJumpHere(v, iAddr);
          if( prNotFound && !pTab->aCol[iCol].notNull ){
            *prNotFound = ++pParse->nMem;
            sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);
          }
        }
      }
    }
  }

  if( eType==0 ){
    /* Could not found an existing table or index to use as the RHS b-tree.
................................................................................
void sqlite4ExprCodeGetColumnOfTable(
  Vdbe *v,        /* The VDBE under construction */
  Table *pTab,    /* The table containing the value */
  int iTabCur,    /* The cursor for this table */
  int iCol,       /* Index of the column to extract */
  int regOut      /* Extract the valud into this register */
){
  if( iCol<0 || iCol==pTab->iPKey ){
    sqlite4VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
  }else{
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
    sqlite4VdbeAddOp3(v, op, iTabCur, iCol, regOut);
  }
  if( iCol>=0 ){
    sqlite4ColumnDefault(v, pTab, iCol, regOut);
................................................................................

    case TK_TRIGGER: {
      /* If the opcode is TK_TRIGGER, then the expression is a reference
      ** to a column in the new.* or old.* pseudo-tables available to
      ** trigger programs. In this case Expr.iTable is set to 1 for the
      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
      ** is set to the column of the pseudo-table to read, or to -1 to
      ** read the rowid field.
      **
      ** The expression is implemented using an OP_Param opcode. The p1
      ** parameter is set to 0 for an old.rowid reference, or to (i+1)
      ** to reference another column of the old.* pseudo-table, where 
      ** i is the index of the column. For a new.rowid reference, p1 is
      ** set to (n+1), where n is the number of columns in each pseudo-table.
      ** For a reference to any other column in the new.* pseudo-table, p1
................................................................................
      **   CREATE TABLE t1(a, b);
      **
      ** Then p1 is interpreted as follows:
      **
      **   p1==0   ->    old.rowid     p1==3   ->    new.rowid
      **   p1==1   ->    old.a         p1==4   ->    new.a
      **   p1==2   ->    old.b         p1==5   ->    new.b       





      */
      Table *pTab = pExpr->pTab;
      int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;

      assert( pExpr->iTable==0 || pExpr->iTable==1 );
      assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
      assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
      assert( p1>=0 && p1<(pTab->nCol*2+2) );

      sqlite4VdbeAddOp2(v, OP_Param, p1, target);
      VdbeComment((v, "%s.%s -> $%d",
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
        target







>
>
>
>







 







<
<

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

|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
<







 







|







 







|







 







>
>
>
>
>






<







1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
....
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
....
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
....
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
....
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
  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
    sqlite4 *db = pParse->db;              /* Database connection */
    Table *pTab;                           /* Table <table>. */
    Expr *pExpr;                           /* Expression <column> */
    int iCol;                              /* Index of column <column> */
    int iDb;                               /* Database idx for pTab */
    Index *pIdx;
    CollSeq *pReq;
    char aff;
    int affinity_ok;

    assert( p );                        /* Because of isCandidateForInOpt(p) */
    assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
    assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
    assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
    pTab = p->pSrc->a[0].pTab;
    pExpr = p->pEList->a[0].pExpr;
................................................................................
    sqlite4TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

    /* This function is only called from two places. In both cases the vdbe
    ** has already been allocated. So assume sqlite4GetVdbe() is always
    ** successful here.
    */
    assert(v);












    /* The collation sequence used by the comparison. If an index is to
    ** be used in place of a temp-table, it must be ordered according
    ** to this collation sequence.  */
    pReq = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);

    /* Check that the affinity that will be used to perform the 
    ** comparison is the same as the affinity of the column. If
    ** it is not, it is not possible to use any index.
    */
    aff = comparisonAffinity(pX);
    affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);

    for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
      if( (pIdx->aiColumn[0]==iCol)
          && sqlite4FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
          && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
        ){
        int iAddr;
        char *pKey;

        pKey = (char *)sqlite4IndexKeyinfo(pParse, pIdx);
        iAddr = sqlite4CodeOnce(pParse);

        sqlite4VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
            pKey,P4_KEYINFO_HANDOFF);
        VdbeComment((v, "%s", pIdx->zName));
        eType = IN_INDEX_INDEX;

        sqlite4VdbeJumpHere(v, iAddr);
        if( prNotFound && !pTab->aCol[iCol].notNull ){
          *prNotFound = ++pParse->nMem;
          sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);

        }
      }
    }
  }

  if( eType==0 ){
    /* Could not found an existing table or index to use as the RHS b-tree.
................................................................................
void sqlite4ExprCodeGetColumnOfTable(
  Vdbe *v,        /* The VDBE under construction */
  Table *pTab,    /* The table containing the value */
  int iTabCur,    /* The cursor for this table */
  int iCol,       /* Index of the column to extract */
  int regOut      /* Extract the valud into this register */
){
  if( iCol<0 ){
    sqlite4VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
  }else{
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
    sqlite4VdbeAddOp3(v, op, iTabCur, iCol, regOut);
  }
  if( iCol>=0 ){
    sqlite4ColumnDefault(v, pTab, iCol, regOut);
................................................................................

    case TK_TRIGGER: {
      /* If the opcode is TK_TRIGGER, then the expression is a reference
      ** to a column in the new.* or old.* pseudo-tables available to
      ** trigger programs. In this case Expr.iTable is set to 1 for the
      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
      ** is set to the column of the pseudo-table to read, or to -1 to
      ** read the rowid field (if applicable - see below).
      **
      ** The expression is implemented using an OP_Param opcode. The p1
      ** parameter is set to 0 for an old.rowid reference, or to (i+1)
      ** to reference another column of the old.* pseudo-table, where 
      ** i is the index of the column. For a new.rowid reference, p1 is
      ** set to (n+1), where n is the number of columns in each pseudo-table.
      ** For a reference to any other column in the new.* pseudo-table, p1
................................................................................
      **   CREATE TABLE t1(a, b);
      **
      ** Then p1 is interpreted as follows:
      **
      **   p1==0   ->    old.rowid     p1==3   ->    new.rowid
      **   p1==1   ->    old.a         p1==4   ->    new.a
      **   p1==2   ->    old.b         p1==5   ->    new.b       
      **
      ** As of SQLite 4, the rowid references are only valid if the table is
      ** declared without an explicit PRIMARY KEY (as it is in the example
      ** above). If the table does have an explicit PRIMARY KEY, the contents
      ** of the old.rowid and new.rowid registers are not defined.
      */
      Table *pTab = pExpr->pTab;
      int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;

      assert( pExpr->iTable==0 || pExpr->iTable==1 );
      assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );

      assert( p1>=0 && p1<(pTab->nCol*2+2) );

      sqlite4VdbeAddOp2(v, OP_Param, p1, target);
      VdbeComment((v, "%s.%s -> $%d",
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
        target

Changes to src/fkey.c.

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
...
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
...
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
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
...
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
...
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
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
...
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
...
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
...
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
**   Register (x+3):      3.1  (type real)
*/

/*
** A foreign key constraint requires that the key columns in the parent
** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
** Given that pParent is the parent table for foreign key constraint pFKey, 
** search the schema a unique index on the parent key columns. 
**
** If successful, zero is returned. If the parent key is an INTEGER PRIMARY 
** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx 
** is set to point to the unique index. 
** 
** If the parent key consists of a single column (the foreign key constraint
** is not a composite foreign key), output variable *paiCol is set to NULL.
** Otherwise, it is set to point to an allocated array of size N, where
** N is the number of columns in the parent key. The first element of the
** array is the index of the child table column that is mapped by the FK
** constraint to the parent table column stored in the left-most column
................................................................................
static int locateFkeyIndex(
  Parse *pParse,                  /* Parse context to store any error in */
  Table *pParent,                 /* Parent table of FK constraint pFKey */
  FKey *pFKey,                    /* Foreign key to find index for */
  Index **ppIdx,                  /* OUT: Unique index on parent table */
  int **paiCol                    /* OUT: Map of index columns in pFKey */
){
  Index *pIdx = 0;                    /* Value to return via *ppIdx */
  int *aiCol = 0;                     /* Value to return via *paiCol */
  int nCol = pFKey->nCol;             /* Number of columns in parent key */
  char *zKey = pFKey->aCol[0].zCol;   /* Name of left-most parent key column */

  /* The caller is responsible for zeroing output parameters. */
  assert( ppIdx && *ppIdx==0 );
  assert( !paiCol || *paiCol==0 );
  assert( pParse );

  /* If this is a non-composite (single column) foreign key, check if it 
  ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx 
  ** and *paiCol set to zero and return early. 
  **

  ** Otherwise, for a composite foreign key (more than one column), allocate
  ** space for the aiCol array (returned via output parameter *paiCol).
  ** Non-composite foreign keys do not require the aiCol array.
  */
  if( nCol==1 ){
    /* The FK maps to the IPK if any of the following are true:
    **
    **   1) There is an INTEGER PRIMARY KEY column and the FK is implicitly 
    **      mapped to the primary key of table pParent, or
    **   2) The FK is explicitly mapped to a column declared as INTEGER
    **      PRIMARY KEY.
    */
    if( pParent->iPKey>=0 ){
      if( !zKey ) return 0;
      if( !sqlite4StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0;
    }
  }else if( paiCol ){
    assert( nCol>1 );
    aiCol = (int *)sqlite4DbMallocRaw(pParse->db, nCol*sizeof(int));
    if( !aiCol ) return 1;
    *paiCol = aiCol;
  }

  for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
    if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ 
      /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
      ** 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{
        /* If zKey is non-NULL, then this foreign key was declared to
        ** map to an explicit list of columns in table pParent. Check if this
        ** index matches those columns. Also, check that the index uses
        ** the default collation sequences for each column. */
        int i, j;
        for(i=0; i<nCol; i++){
          int iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
          char *zDfltColl;                  /* Def. collation for column */
          char *zIdxCol;                    /* Name of indexed column */

          /* If the index uses a collation sequence that is different from
................................................................................
static void fkLookupParent(
  Parse *pParse,        /* Parse context */
  int iDb,              /* Index of database housing pTab */
  Table *pTab,          /* Parent table of FK pFKey */
  Index *pIdx,          /* Unique index on parent key columns in pTab */
  FKey *pFKey,          /* Foreign key constraint */
  int *aiCol,           /* Map from parent key columns to child table columns */
  int regData,          /* Address of array containing child table row */
  int nIncr,            /* Increment constraint counter by this */
  int isIgnore          /* If true, pretend pTab contains all NULL values */
){
  int i;                                    /* Iterator variable */
  Vdbe *v = sqlite4GetVdbe(pParse);         /* Vdbe to add code to */
  int iCur = pParse->nTab - 1;              /* Cursor number to use */
  int iOk = sqlite4VdbeMakeLabel(v);        /* jump here if parent key found */

  /* If nIncr is less than zero, then check at runtime if there are any
  ** outstanding constraints to resolve. If there are not, there is no need
  ** to check if deleting this row resolves any outstanding violations.
  **
  ** Check if any of the key columns in the child table row are NULL. If 
  ** any are, then the constraint is considered satisfied. No need to 
  ** search for a matching row in the parent table.  */
  if( nIncr<0 ){
    sqlite4VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
  }




  for(i=0; i<pFKey->nCol; i++){
    int iReg = aiCol[i] + regData + 1;
    sqlite4VdbeAddOp2(v, OP_IsNull, iReg, iOk);
  }

  if( isIgnore==0 ){
    if( pIdx==0 ){
      /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
      ** column of the parent table (table pTab).  */
      int iMustBeInt;               /* Address of MustBeInt instruction */
      int regTemp = sqlite4GetTempReg(pParse);
  
      /* Invoke MustBeInt to coerce the child key value to an integer (i.e. 
      ** apply the affinity of the parent key). If this fails, then there
      ** is no matching parent key. Before using MustBeInt, make a copy of
      ** the value. Otherwise, the value inserted into the child key column
      ** will have INTEGER affinity applied to it, which may not be correct.  */
      sqlite4VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
      iMustBeInt = sqlite4VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter.  */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        sqlite4VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
      }
  
      sqlite4OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
      sqlite4VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
      sqlite4VdbeAddOp2(v, OP_Goto, 0, iOk);
      sqlite4VdbeJumpHere(v, sqlite4VdbeCurrentAddr(v)-2);
      sqlite4VdbeJumpHere(v, iMustBeInt);
      sqlite4ReleaseTempReg(pParse, regTemp);
    }else{
      int nCol = pFKey->nCol;
      int regTemp = sqlite4GetTempRange(pParse, nCol);
      int regRec = sqlite4GetTempReg(pParse);
      KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIdx);
  
      sqlite4VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
      sqlite4VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);




      for(i=0; i<nCol; i++){
        sqlite4VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
      }


  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter. 
      **
      ** If any of the parent-key values are NULL, then the row cannot match 
      ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
      ** of the parent-key values are NULL (at this point it is known that
      ** none of the child key values are).
      */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        int iJump = sqlite4VdbeCurrentAddr(v) + nCol + 1;
        for(i=0; i<nCol; i++){
          int iChild = aiCol[i]+1+regData;
          int iParent = pIdx->aiColumn[i]+1+regData;
          assert( aiCol[i]!=pTab->iPKey );
          if( pIdx->aiColumn[i]==pTab->iPKey ){
            /* The parent key is a composite key that includes the IPK column */
            iParent = regData;
          }
          sqlite4VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
          sqlite4VdbeChangeP5(v, SQLITE_JUMPIFNULL);

        }
        sqlite4VdbeAddOp2(v, OP_Goto, 0, iOk);
      }
  




      sqlite4VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
      sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v,pIdx), P4_TRANSIENT);
      sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);

  
      sqlite4ReleaseTempReg(pParse, regRec);
      sqlite4ReleaseTempRange(pParse, regTemp, nCol);
    }
  }

  if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
    /* Special case: If this is an INSERT statement that will insert exactly
    ** one row into the table, raise a constraint immediately instead of
    ** incrementing a counter. This is necessary as the VM code is being
    ** generated for will not open a statement transaction.  */
................................................................................
  }

  sqlite4VdbeResolveLabel(v, iOk);
  sqlite4VdbeAddOp1(v, OP_Close, iCur);
}

/*
** This function is called to generate code executed when a row is deleted
** from the parent table of foreign key constraint pFKey and, if pFKey is 
** deferred, when a row is inserted into the same table. When generating
** code for an SQL UPDATE operation, this function may be called twice -
** once to "delete" the old row and once to "insert" the new row.

**
** The code generated by this function scans through the rows in the child
** table that correspond to the parent table row being deleted or inserted.
** For each child row found, one of the following actions is taken:
**
**   Operation | FK type   | Action taken
**   --------------------------------------------------------------------------
................................................................................
  int i;                          /* Iterator variable */
  Expr *pWhere = 0;               /* WHERE clause to scan with */
  NameContext sNameContext;       /* Context used to resolve WHERE clause */
  WhereInfo *pWInfo;              /* Context used by sqlite4WhereXXX() */
  int iFkIfZero = 0;              /* Address of OP_FkIfZero */
  Vdbe *v = sqlite4GetVdbe(pParse);

  assert( !pIdx || pIdx->pTable==pTab );

  if( nIncr<0 ){
    iFkIfZero = sqlite4VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
  }

  /* Create an Expr object representing an SQL expression like:
  **
................................................................................
    int iCol;                     /* Index of column in child table */ 
    const char *zCol;             /* Name of column in child table */

    pLeft = sqlite4Expr(db, TK_REGISTER, 0);
    if( pLeft ){
      /* Set the collation sequence and affinity of the LHS of each TK_EQ
      ** expression to the parent key column defaults.  */
      if( pIdx ){
        Column *pCol;
        iCol = pIdx->aiColumn[i];
        pCol = &pTab->aCol[iCol];
        if( pTab->iPKey==iCol ) iCol = -1;
        pLeft->iTable = regData+iCol+1;
        pLeft->affinity = pCol->affinity;
        pLeft->pColl = sqlite4LocateCollSeq(pParse, pCol->zColl);
      }else{
        pLeft->iTable = regData;
        pLeft->affinity = SQLITE_AFF_INTEGER;
      }
    }
    iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
    assert( iCol>=0 );
    zCol = pFKey->pFrom->aCol[iCol].zName;
    pRight = sqlite4Expr(db, TK_ID, zCol);
    pEq = sqlite4PExpr(pParse, TK_EQ, pLeft, pRight, 0);
    pWhere = sqlite4ExprAnd(db, pWhere, pEq);
................................................................................
  /* Resolve the references in the WHERE clause. */
  memset(&sNameContext, 0, sizeof(NameContext));
  sNameContext.pSrcList = pSrc;
  sNameContext.pParse = pParse;
  sqlite4ResolveExprNames(&sNameContext, pWhere);

  /* Create VDBE to loop through the entries in pSrc that match the WHERE
  ** clause. If the constraint is not deferred, throw an exception for
  ** each row found. Otherwise, for deferred constraints, increment the
  ** deferred constraint counter by nIncr for each row selected.  */
  pWInfo = sqlite4WhereBegin(pParse, pSrc, pWhere, 0, 0, 0);
  if( nIncr>0 && pFKey->isDeferred==0 ){
    sqlite4ParseToplevel(pParse)->mayAbort = 1;
  }
  sqlite4VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
  if( pWInfo ){
    sqlite4WhereEnd(pWInfo);
................................................................................

    if( aiFree ){
      aiCol = aiFree;
    }else{
      iCol = pFKey->aCol[0].iFrom;
      aiCol = &iCol;
    }
    for(i=0; i<pFKey->nCol; i++){
      if( aiCol[i]==pTab->iPKey ){
        aiCol[i] = -1;
      }
#ifndef SQLITE_OMIT_AUTHORIZATION

      /* Request permission to read the parent key columns. If the 
      ** authorization callback returns SQLITE_IGNORE, behave as if any
      ** values read from the parent table are NULL. */
      if( db->xAuth ){
        int rcauth;
        char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
        rcauth = sqlite4AuthReadCol(pParse, pTo->zName, zCol, iDb);
        isIgnore = (rcauth==SQLITE_IGNORE);
      }
#endif
    }


    /* Take a shared-cache advisory read-lock on the parent table. Allocate 
    ** a cursor to use to search the unique index on the parent key columns 
    ** in the parent table.  */
    sqlite4TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName);
    pParse->nTab++;

................................................................................
  }
}

#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))

/*
** This function is called before generating code to update or delete a 
** row contained in table pTab.
*/
u32 sqlite4FkOldmask(
  Parse *pParse,                  /* Parse context */
  Table *pTab                     /* Table being modified */
){
  u32 mask = 0;
  if( pParse->db->flags&SQLITE_ForeignKeys ){
................................................................................
** If any foreign key processing will be required, this function returns
** true. If there is no foreign key related processing, this function 
** returns false.
*/
int sqlite4FkRequired(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table being modified */
  int *aChange,                   /* Non-NULL for UPDATE operations */
  int chngRowid                   /* True for UPDATE that affects rowid */
){
  if( pParse->db->flags&SQLITE_ForeignKeys ){
    if( !aChange ){
      /* A DELETE operation. Foreign key processing is required if the 
      ** table in question is either the child or parent table for any 
      ** foreign key constraint.  */
      return (sqlite4FkReferences(pTab) || pTab->pFKey);
................................................................................
      FKey *p;

      /* Check if any child key columns are being modified. */
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        for(i=0; i<p->nCol; i++){
          int iChildKey = p->aCol[i].iFrom;
          if( aChange[iChildKey]>=0 ) return 1;
          if( iChildKey==pTab->iPKey && chngRowid ) return 1;
        }
      }

      /* Check if any parent key columns are being modified. */
      for(p=sqlite4FkReferences(pTab); p; p=p->pNextTo){
        for(i=0; i<p->nCol; i++){
          char *zKey = p->aCol[i].zCol;
          int iKey;
          for(iKey=0; iKey<pTab->nCol; iKey++){
            Column *pCol = &pTab->aCol[iKey];
            if( (zKey ? !sqlite4StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
              if( aChange[iKey]>=0 ) return 1;
              if( iKey==pTab->iPKey && chngRowid ) return 1;
            }
          }
        }
      }
    }
  }
  return 0;







|

|
<
|







 







|
|
|
|






|
<
<
<
>
|

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












|
|
<
<
<







|
|
|
|







 







|








|
|
|
|
|
|
<



>
>
>
>

|




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







 







|
|
<
|
|
>







 







|







 







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







 







|
|
<







 







<
<
<
<

>





|



<

>







 







|







 







|
<







 







<












<







138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
...
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
...
295
296
297
298
299
300
301
302
303
304
305
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
...
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
...
462
463
464
465
466
467
468

469
470
471

472
473
474




475
476
477
478
479
480
481
...
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
...
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
...
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
...
837
838
839
840
841
842
843
844

845
846
847
848
849
850
851
...
856
857
858
859
860
861
862

863
864
865
866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
**   Register (x+3):      3.1  (type real)
*/

/*
** A foreign key constraint requires that the key columns in the parent
** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
** Given that pParent is the parent table for foreign key constraint pFKey, 
** search the schema for a unique index on the parent key columns. 
**
** If successful, zero is returned and *ppIdx is set to point to the 

** unique index.
** 
** If the parent key consists of a single column (the foreign key constraint
** is not a composite foreign key), output variable *paiCol is set to NULL.
** Otherwise, it is set to point to an allocated array of size N, where
** N is the number of columns in the parent key. The first element of the
** array is the index of the child table column that is mapped by the FK
** constraint to the parent table column stored in the left-most column
................................................................................
static int locateFkeyIndex(
  Parse *pParse,                  /* Parse context to store any error in */
  Table *pParent,                 /* Parent table of FK constraint pFKey */
  FKey *pFKey,                    /* Foreign key to find index for */
  Index **ppIdx,                  /* OUT: Unique index on parent table */
  int **paiCol                    /* OUT: Map of index columns in pFKey */
){
  Index *pIdx = 0;                /* Value to return via *ppIdx */
  int *aiCol = 0;                 /* Value to return via *paiCol */
  int nCol = pFKey->nCol;         /* Number of columns in parent key */
  int bImplicit;                  /* True if no explicit parent columns */

  /* The caller is responsible for zeroing output parameters. */
  assert( ppIdx && *ppIdx==0 );
  assert( !paiCol || *paiCol==0 );
  assert( pParse );

  bImplicit = (pFKey->aCol[0].zCol==0);




  /* If this is a composite foreign key (more than one column), allocate
  ** space for the aiCol array (returned via output parameter *paiCol).
  ** Non-composite foreign keys do not require the aiCol array.  */













  if( paiCol && nCol>1 ){
    assert( nCol>1 );
    aiCol = (int *)sqlite4DbMallocRaw(pParse->db, nCol*sizeof(int));
    if( !aiCol ) return 1;
    *paiCol = aiCol;
  }

  for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
    if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ 
      /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
      ** of columns. If each indexed column corresponds to a foreign key
      ** column of pFKey, then this index is a winner.  */

      if( bImplicit ){
        if( pIdx->eIndexType==SQLITE_INDEX_PRIMARYKEY ){



          if( aiCol ){
            int i;
            for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
          }
          break;
        }
      }else{
        /* If this foreign key was declared to map to an explicit list of 
        ** columns in table pParent. Check if this index matches those 
        ** columns. Also, check that the index uses the default collation 
        ** sequences for each column. */
        int i, j;
        for(i=0; i<nCol; i++){
          int iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
          char *zDfltColl;                  /* Def. collation for column */
          char *zIdxCol;                    /* Name of indexed column */

          /* If the index uses a collation sequence that is different from
................................................................................
static void fkLookupParent(
  Parse *pParse,        /* Parse context */
  int iDb,              /* Index of database housing pTab */
  Table *pTab,          /* Parent table of FK pFKey */
  Index *pIdx,          /* Unique index on parent key columns in pTab */
  FKey *pFKey,          /* Foreign key constraint */
  int *aiCol,           /* Map from parent key columns to child table columns */
  int regContent,       /* Address of array containing child table row */
  int nIncr,            /* Increment constraint counter by this */
  int isIgnore          /* If true, pretend pTab contains all NULL values */
){
  int i;                                    /* Iterator variable */
  Vdbe *v = sqlite4GetVdbe(pParse);         /* Vdbe to add code to */
  int iCur = pParse->nTab - 1;              /* Cursor number to use */
  int iOk = sqlite4VdbeMakeLabel(v);        /* jump here if parent key found */

  assert( pIdx );

  /* If nIncr is less than zero (this is a DELETE), then check at runtime if
  ** there are any outstanding constraints to resolve. If there are not, 
  ** there is no need to check if deleting this row resolves any outstanding 
  ** violations.  */

  if( nIncr<0 ){
    sqlite4VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
  }

  /* Check if any of the key columns in the child table row are NULL. If 
  ** any are, then the constraint is considered satisfied. No need to 
  ** search for a matching row in the parent table.  */
  for(i=0; i<pFKey->nCol; i++){
    int iReg = aiCol[i] + regContent;
    sqlite4VdbeAddOp2(v, OP_IsNull, iReg, iOk);
  }

  if( isIgnore==0 ){





























    int nCol = pFKey->nCol;
    int regTemp = sqlite4GetTempRange(pParse, nCol);
    int regRec = sqlite4GetTempReg(pParse);




    sqlite4OpenIndex(pParse, iCur, iDb, pIdx, OP_OpenRead);

    /* Assemble the child key values in a contiguous array of registers.
    ** Then apply the affinity transformation for the parent index.  */
    for(i=0; i<nCol; i++){
      sqlite4VdbeAddOp2(v, OP_Copy, aiCol[i]+regContent, regTemp+i);
    }
    sqlite4VdbeAddOp2(v, OP_Affinity, regTemp, nCol);
    sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v, pIdx), P4_TRANSIENT);

    /* If the parent table is the same as the child table, and we are about
    ** to increment the constraint-counter (i.e. this is an INSERT operation),
    ** then check if the row being inserted matches itself. If so, do not
    ** increment the constraint-counter. 
    **
    ** If any of the parent-key values are NULL, then the row cannot match 
    ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
    ** of the parent-key values are NULL (at this point it is known that
    ** none of the child key values are).  */

    if( pTab==pFKey->pFrom && nIncr==1 ){
      int iJump = sqlite4VdbeCurrentAddr(v) + nCol + 1;
      for(i=0; i<nCol; i++){
        int iChild = regTemp+i;
        int iParent = pIdx->aiColumn[i]+regContent;





        sqlite4VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
        sqlite4VdbeChangeP5(v, SQLITE_JUMPIFNULL);
        assert( iChild<=pParse->nMem && iParent<=pParse->nMem );
      }
      sqlite4VdbeAddOp2(v, OP_Goto, 0, iOk);
    }

    sqlite4VdbeAddOp4Int(v, OP_MakeIdxKey, iCur, regTemp, regRec, nCol);
    sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);

#if 0
    sqlite4VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
    sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v,pIdx), P4_TRANSIENT);
    sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
#endif

    sqlite4ReleaseTempReg(pParse, regRec);
    sqlite4ReleaseTempRange(pParse, regTemp, nCol);

  }

  if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
    /* Special case: If this is an INSERT statement that will insert exactly
    ** one row into the table, raise a constraint immediately instead of
    ** incrementing a counter. This is necessary as the VM code is being
    ** generated for will not open a statement transaction.  */
................................................................................
  }

  sqlite4VdbeResolveLabel(v, iOk);
  sqlite4VdbeAddOp1(v, OP_Close, iCur);
}

/*
** This function is called to generate code executed when a row is inserted
** into or deleted from the parent table of foreign key constraint pFKey.

** When generating code for an SQL UPDATE operation, this function may be 
** called twice - once to "delete" the old row and once to "insert" the 
** new row.
**
** The code generated by this function scans through the rows in the child
** table that correspond to the parent table row being deleted or inserted.
** For each child row found, one of the following actions is taken:
**
**   Operation | FK type   | Action taken
**   --------------------------------------------------------------------------
................................................................................
  int i;                          /* Iterator variable */
  Expr *pWhere = 0;               /* WHERE clause to scan with */
  NameContext sNameContext;       /* Context used to resolve WHERE clause */
  WhereInfo *pWInfo;              /* Context used by sqlite4WhereXXX() */
  int iFkIfZero = 0;              /* Address of OP_FkIfZero */
  Vdbe *v = sqlite4GetVdbe(pParse);

  assert( pIdx && pIdx->pTable==pTab );

  if( nIncr<0 ){
    iFkIfZero = sqlite4VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
  }

  /* Create an Expr object representing an SQL expression like:
  **
................................................................................
    int iCol;                     /* Index of column in child table */ 
    const char *zCol;             /* Name of column in child table */

    pLeft = sqlite4Expr(db, TK_REGISTER, 0);
    if( pLeft ){
      /* Set the collation sequence and affinity of the LHS of each TK_EQ
      ** expression to the parent key column defaults.  */

      Column *pCol;
      iCol = pIdx->aiColumn[i];
      pCol = &pTab->aCol[iCol];

      pLeft->iTable = regData+iCol;
      pLeft->affinity = pCol->affinity;
      pLeft->pColl = sqlite4LocateCollSeq(pParse, pCol->zColl);




    }
    iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
    assert( iCol>=0 );
    zCol = pFKey->pFrom->aCol[iCol].zName;
    pRight = sqlite4Expr(db, TK_ID, zCol);
    pEq = sqlite4PExpr(pParse, TK_EQ, pLeft, pRight, 0);
    pWhere = sqlite4ExprAnd(db, pWhere, pEq);
................................................................................
  /* Resolve the references in the WHERE clause. */
  memset(&sNameContext, 0, sizeof(NameContext));
  sNameContext.pSrcList = pSrc;
  sNameContext.pParse = pParse;
  sqlite4ResolveExprNames(&sNameContext, pWhere);

  /* Create VDBE to loop through the entries in pSrc that match the WHERE
  ** clause. For each row found, increment the relevant constraint counter
  ** by nIncr.  */

  pWInfo = sqlite4WhereBegin(pParse, pSrc, pWhere, 0, 0, 0);
  if( nIncr>0 && pFKey->isDeferred==0 ){
    sqlite4ParseToplevel(pParse)->mayAbort = 1;
  }
  sqlite4VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
  if( pWInfo ){
    sqlite4WhereEnd(pWInfo);
................................................................................

    if( aiFree ){
      aiCol = aiFree;
    }else{
      iCol = pFKey->aCol[0].iFrom;
      aiCol = &iCol;
    }




#ifndef SQLITE_OMIT_AUTHORIZATION
    for(i=0; i<pFKey->nCol; i++){
      /* Request permission to read the parent key columns. If the 
      ** authorization callback returns SQLITE_IGNORE, behave as if any
      ** values read from the parent table are NULL. */
      if( db->xAuth ){
        int rcauth;
        char *zCol = pTo->aCol[pIdx->aiColumn[i]].zName;
        rcauth = sqlite4AuthReadCol(pParse, pTo->zName, zCol, iDb);
        isIgnore = (rcauth==SQLITE_IGNORE);
      }

    }
#endif

    /* Take a shared-cache advisory read-lock on the parent table. Allocate 
    ** a cursor to use to search the unique index on the parent key columns 
    ** in the parent table.  */
    sqlite4TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName);
    pParse->nTab++;

................................................................................
  }
}

#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))

/*
** This function is called before generating code to update or delete a 
** row contained in table pTab. 
*/
u32 sqlite4FkOldmask(
  Parse *pParse,                  /* Parse context */
  Table *pTab                     /* Table being modified */
){
  u32 mask = 0;
  if( pParse->db->flags&SQLITE_ForeignKeys ){
................................................................................
** If any foreign key processing will be required, this function returns
** true. If there is no foreign key related processing, this function 
** returns false.
*/
int sqlite4FkRequired(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table being modified */
  int *aChange                    /* Non-NULL for UPDATE operations */

){
  if( pParse->db->flags&SQLITE_ForeignKeys ){
    if( !aChange ){
      /* A DELETE operation. Foreign key processing is required if the 
      ** table in question is either the child or parent table for any 
      ** foreign key constraint.  */
      return (sqlite4FkReferences(pTab) || pTab->pFKey);
................................................................................
      FKey *p;

      /* Check if any child key columns are being modified. */
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        for(i=0; i<p->nCol; i++){
          int iChildKey = p->aCol[i].iFrom;
          if( aChange[iChildKey]>=0 ) return 1;

        }
      }

      /* Check if any parent key columns are being modified. */
      for(p=sqlite4FkReferences(pTab); p; p=p->pNextTo){
        for(i=0; i<p->nCol; i++){
          char *zKey = p->aCol[i].zCol;
          int iKey;
          for(iKey=0; iKey<pTab->nCol; iKey++){
            Column *pCol = &pTab->aCol[iKey];
            if( (zKey ? !sqlite4StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
              if( aChange[iKey]>=0 ) return 1;

            }
          }
        }
      }
    }
  }
  return 0;

Changes to src/global.c.

166
167
168
169
170
171
172







173
174
175
176
177
178
179
   0,                         /* isMallocInit */
   0,                         /* isPCacheInit */
   0,                         /* pInitMutex */
   0,                         /* nRefInitMutex */
   0,                         /* xLog */
   0,                         /* pLogArg */
   0,                         /* bLocaltimeFault */







};


/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is
** read-only.







>
>
>
>
>
>
>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
   0,                         /* isMallocInit */
   0,                         /* isPCacheInit */
   0,                         /* pInitMutex */
   0,                         /* nRefInitMutex */
   0,                         /* xLog */
   0,                         /* pLogArg */
   0,                         /* bLocaltimeFault */

#ifdef SQLITE_ENABLE_LSM
   sqlite4KVStoreOpenLsm,     /* xKVFile */
#else
   sqlite4KVStoreOpenMem,     /* xKVFile */
#endif
   sqlite4KVStoreOpenMem,     /* xKVTmp */
};


/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is
** read-only.

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
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
...
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
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
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
868
869




870
871


872
873
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976


977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995

996
997
998


999
1000
1001
1002
1003
1004
1005
....
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
....
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
....
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
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

  db = pParse->db;
  memset(&dest, 0, sizeof(dest));
  if( pParse->nErr || db->mallocFailed ){
    goto insert_cleanup;
  }

  /* Locate the table into which we will be inserting new information.
  */
  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( NEVER(zTab==0) ) goto insert_cleanup;
  pTab = sqlite4SrcListLookup(pParse, pTabList);
  if( pTab==0 ){
    goto insert_cleanup;
  }
................................................................................
  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;
#else
# define pTrigger 0
# define tmask 0
# define isView 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);

    /* build the NEW.* reference row.  Note that if there is an INTEGER
    ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has
    ** not happened yet) so we substitute a rowid of -1
    */
    if( keyColumn<0 ){
      sqlite4VdbeAddOp2(v, OP_Integer, -1, regCols);
    }else{
      int j1;
      if( useTempTable ){
        sqlite4VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
      }else{
        assert( pSelect==0 );  /* Otherwise useTempTable is true */
        sqlite4ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
      }
      j1 = sqlite4VdbeAddOp1(v, OP_NotNull, regCols);
      sqlite4VdbeAddOp2(v, OP_Integer, -1, regCols);
      sqlite4VdbeJumpHere(v, j1);
      sqlite4VdbeAddOp1(v, OP_MustBeInt, regCols);
    }

    /* Cannot have triggers on a virtual table. If it were possible,
    ** this block would have to account for hidden column.
    */
    assert( !IsVirtual(pTab) );

    /* Create the new column data
    */
    for(i=0; i<pTab->nCol; i++){
      if( pColumn==0 ){
        j = i;
      }else{

        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
        }
      }

      if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){
        sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
      }else if( useTempTable ){
        sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); 


      }else{
        assert( pSelect==0 ); /* Otherwise useTempTable is true */
        sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
      }
    }

    /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite4VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
      sqlite4TableAffinityStr(v, pTab);
    }

    /* 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( pSelect ){
        sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
      }else{
        VdbeOp *pOp;
        sqlite4ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
        pOp = sqlite4VdbeGetOp(v, -1);
        if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
          appendFlag = 1;
          pOp->opcode = OP_NewRowid;
          pOp->p1 = baseCur;
          pOp->p2 = regRowid;
          pOp->p3 = regAutoinc;
        }
      }
      /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
      ** to generate a unique primary key value.
      */
      if( !appendFlag ){
        int j1;
        if( !IsVirtual(pTab) ){
          j1 = sqlite4VdbeAddOp1(v, OP_NotNull, regRowid);
          sqlite4VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
          sqlite4VdbeJumpHere(v, j1);
        }else{
          j1 = sqlite4VdbeCurrentAddr(v);
          sqlite4VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
        }
        sqlite4VdbeAddOp1(v, OP_MustBeInt, 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;
        }
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
        }
      }
      if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
        sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
      }else if( useTempTable ){
        sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); 
      }else if( pSelect ){
        sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
      }else{
        sqlite4ExprCode(pParse, pList->a[j].pExpr, iRegStore);
      }
    }

    /* Generate code to check constraints and generate index keys and
    ** do the insertion.
    */

#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
      sqlite4VtabMakeWritable(pParse, pTab);
      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 ){
    sqlite4VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
  }

  if( pTrigger ){
    /* Code AFTER triggers */

    sqlite4CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, 
        pTab, regData-2-pTab->nCol, onError, endOfLoop);
  }



  /* The bottom of the main insertion loop, if the data source
  ** is a SELECT statement.
  */
  sqlite4VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
    sqlite4VdbeAddOp2(v, OP_Next, srcTab, addrCont);
................................................................................
  }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
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
    sqlite4AutoincrementEnd(pParse);
  }

  /*
  ** Return the number of rows inserted. If this routine is 
  ** generating code because of a call to sqlite4NestedParse(), do not
  ** invoke the callback function.
  */
  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
    sqlite4VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
    sqlite4VdbeSetNumCols(v, 1);
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
  }

insert_cleanup:
  sqlite4SrcListDelete(db, pTabList);
  sqlite4ExprListDelete(db, pList);
  sqlite4SelectDelete(db, pSelect);
  sqlite4IdListDelete(db, pColumn);
  sqlite4DbFree(db, aRegIdx);
}
................................................................................
#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
................................................................................
  ** the extra complication to make this rule less restrictive is probably
  ** not worth the effort.  Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
  */
  if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
    return 0;
  }
#endif
  if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
    return 0;  /* xfer opt does not play well with PRAGMA count_changes */
  }

  /* If we get this far, it means that the xfer optimization is at
  ** least a possibility, though it might only work if the destination
  ** table (tab1) is initially empty.
  */
#ifdef SQLITE_TEST
  sqlite4_xferopt_count++;







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

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





|
>
>
>
>









<
<
<





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

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



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







 







<
<
<







 







<



>
>
>
>
>
>
>













|
<







 








>
>
>
>
>
>
>
>

|
<







 







|
<





|
|





|
<







 







<
<
<
<
<







 







>







 







|
|







 







|










|
|
|
<
<
<
<
<
<






>

|

<
<
<



|
<
<
<
|

|
|
<




|
|
|
|
|
|
<
<
<
>

<
<
<
<
<
<




|







 







|
|
|
>
>
|
|
>

>
>



<

<
<

<
<

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

<
<
<
<
<
|
|
|
|

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










>
>

|
|

|
|
|




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







 







<
|













<
<
<
<
<
<
<
<
<
<
<







 







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

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







 







|
|

|





>
>
>




<
<
<



<





>
|

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





<
<
>
>
>



|
>
>
>
|
>
>


<
|
<
>
>
>
>
|


<
<
|
<
<
>

<
>
>
>
>

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

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










<
<
<


>
>
>
>
>
>
>
>
>
>
>





|







<


<



>


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



|
<

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









|





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



|
|
>

<
<
|
<
<
<
<
<
>

<
<
<
<







 







<
<
<







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
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
...
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
...
622
623
624
625
626
627
628





629
630
631
632
633
634
635
...
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
...
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
...
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
...
835
836
837
838
839
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
868
869
870
871
872
873
874
875
876
877
878





879
880
881
882
883
884
885
886
887
888
889

890
891
892

893






894
895


896
897















898

































































899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922







923
924
925


926
927
928
929
930
931
932
933
934
...
937
938
939
940
941
942
943

944
945
946
947
948
949
950
951
952
953
954
955
956
957











958
959
960
961
962
963
964
...
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
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
....
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
....
1709
1710
1711
1712
1713
1714
1715



1716
1717
1718
1719
1720
1721
1722
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

  db = pParse->db;
  memset(&dest, 0, sizeof(dest));
  if( pParse->nErr || db->mallocFailed ){
    goto insert_cleanup;
  }

  /* Locate the table into which we will be inserting new information. */

  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( NEVER(zTab==0) ) goto insert_cleanup;
  pTab = sqlite4SrcListLookup(pParse, pTabList);
  if( pTab==0 ){
    goto insert_cleanup;
  }
................................................................................
  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.
  ** Also set pPk to point to the primary key, and iPk to the cursor offset
  ** of the primary key cursor (i.e. so that the cursor opened on the primary
  ** key index is VDBE cursor (baseCur+iPk).  */
  pPk = sqlite4FindPrimaryKey(pTab, &iPk);
  assert( (pPk==0)==IsView(pTab) );
  bImplicitPK = (pPk && 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;
#else
# define pTrigger 0
# define tmask 0
# define isView 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;

      }
    }
  }

  /* 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.  */
  regRowid = ++pParse->nMem;
  regContent = pParse->nMem+1;
  pParse->nMem += pTab->nCol;

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




  endOfLoop = sqlite4VdbeMakeLabel(v);
































  for(i=0; i<pTab->nCol; i++){

    j = i;

    if( pColumn ){
      for(j=0; j<pColumn->nId; j++){
        if( pColumn->a[j].idx==i ) break;
      }
    }

    if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
      sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regContent+i);
    }else if( useTempTable ){
      sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regContent+i);
    }else if( pSelect ){
      sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, regContent+i);
    }else{
      assert( pSelect==0 ); /* Otherwise useTempTable is true */
      sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regContent+i);
    }
  }






  if( !isView ){
    sqlite4VdbeAddOp2(v, OP_Affinity, regContent, pTab->nCol);
    sqlite4TableAffinityStr(v, pTab);
  }

  /* Fire BEFORE or INSTEAD OF triggers */
  if( pTrigger ){
    sqlite4VdbeAddOp2(v, OP_Integer, -1, regRowid);
    VdbeComment((v, "new.rowid value for BEFORE triggers"));
    sqlite4CodeRowTrigger(
        pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 

        pTab, (regRowid - pTab->nCol - 1), onError, endOfLoop
    );
  }








  if( bImplicitPK ){
    assert( !isView );


    sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur+iPk, regRowid);
  }

















































































  if( !isView ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
      sqlite4VtabMakeWritable(pParse, pTab);
      sqlite4VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
      sqlite4VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
      sqlite4MayAbort(pParse);
    }else
#endif
    {
      /* Generate code to check constraints and generate index keys and
      ** do the insertion.  */
      int isReplace;    /* Set to true if constraints may cause a replace */
      sqlite4GenerateConstraintChecks(pParse, pTab, baseCur, 
          regContent, aRegIdx, 0, 0, onError, endOfLoop, &isReplace
      );
      sqlite4FkCheck(pParse, pTab, 0, regContent);
      sqlite4CompleteInsertion(pParse, pTab, baseCur, 
          regContent, aRegIdx, 0, appendFlag, isReplace==0
      );
    }
  }








  /* Code AFTER triggers */
  sqlite4CodeRowTrigger(
      pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, 


      pTab, regRowid - pTab->nCol - 1, onError, endOfLoop
  );

  /* The bottom of the main insertion loop, if the data source
  ** is a SELECT statement.
  */
  sqlite4VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
    sqlite4VdbeAddOp2(v, OP_Next, srcTab, addrCont);
................................................................................
  }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
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
    sqlite4AutoincrementEnd(pParse);
  }












insert_cleanup:
  sqlite4SrcListDelete(db, pTabList);
  sqlite4ExprListDelete(db, pList);
  sqlite4SelectDelete(db, pSelect);
  sqlite4IdListDelete(db, pColumn);
  sqlite4DbFree(db, aRegIdx);
}
................................................................................
#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;
}

/*
** Index pIdx is a UNIQUE index. This function returns a pointer to a buffer
** containing an error message to tell the user that the UNIQUE constraint
** has failed.
**
** The returned buffer should be freed by the caller using sqlite4DbFree().
*/
static char *notUniqueMessage(
  Parse *pParse,                  /* Parse context */
  Index *pIdx                     /* Index to generate error message for */
){
  const int nCol = pIdx->nColumn; /* Number of columns indexed by pIdx */
  StrAccum errMsg;                /* Buffer to build error message within */
  int iCol;                       /* Used to iterate through indexed columns */

  sqlite4StrAccumInit(&errMsg, 0, 0, 200);
  errMsg.db = pParse->db;
  sqlite4StrAccumAppend(&errMsg, (nCol>1 ? "columns " : "column "), -1);
  for(iCol=0; iCol<pIdx->nColumn; iCol++){
    const char *zCol = indexColumnName(pIdx, iCol);
    sqlite4StrAccumAppend(&errMsg, (iCol==0 ? "" : ", "), -1);
    sqlite4StrAccumAppend(&errMsg, zCol, -1);
  }
  sqlite4StrAccumAppend(&errMsg, (nCol>1 ? " are" : " is"), -1);
  sqlite4StrAccumAppend(&errMsg, " not unique", -1);
  return sqlite4StrAccumFinish(&errMsg);
}

/*
** 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. In this case
**   any UNIQUE constraint 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 regOldKey,      /* For an update, the original encoded PK */
  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 */
){
  u8 aPkRoot[10];                 /* Root page number for pPk as a varint */ 
  int nPkRoot;                    /* Size of aPkRoot in bytes */
  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);
  nPkRoot = sqlite4PutVarint64(aPkRoot, pPk->tnum);

  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 regPk;                    /* PK of conflicting row (for REPLACE) */

    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);
    regPk = 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]);


    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 */
      int iTest2 = 0;             /* Address of OP_Eq instruction */
      int regOut = 0;             /* PK of row to replace */

      /* 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;
      }




      if( onError==OE_Replace ){
        sqlite4VdbeAddOp3(v, OP_Blob, nPkRoot, regPk, 0);
        sqlite4VdbeChangeP4(v, -1, aPkRoot, nPkRoot);
        regOut = regPk;
      }
      if( regOldKey && pIdx==pPk ){
        iTest2 = sqlite4VdbeAddOp3(v, OP_Eq, regOldKey, 0, aRegIdx[iCur]);
      }
      iTest = sqlite4VdbeAddOp3(v, OP_IsUnique, baseCur+iCur, 0, aRegIdx[iCur]);
      sqlite4VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(regOut), P4_INT32);


      



      switch( onError ){
        case OE_Rollback:
        case OE_Abort:
        case OE_Fail: {



          char *zErr = notUniqueMessage(pParse, pIdx);













          sqlite4HaltConstraint(pParse, onError, zErr, 0);
          sqlite4DbFree(pParse->db, zErr);
          break;
        }

        case OE_Ignore: {
          assert( seenReplace==0 );
          sqlite4VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
          break;
        }
        default: {
          Trigger *pTrigger;
          assert( onError==OE_Replace );
          sqlite4MultiWrite(pParse);

          pTrigger = sqlite4TriggersExist(pParse, pTab, TK_DELETE, 0, 0);

          sqlite4GenerateRowDelete(
              pParse, pTab, baseCur, regOut, 0, pTrigger, OE_Replace
          );
          seenReplace = 1;
          break;
        }
      }

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

    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]);
      sqlite4VdbeChangeP5(v, 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 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 );
  assert( pTab->pIndex==0 || IsView(pTab)==0 );

  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
................................................................................
  ** the extra complication to make this rule less restrictive is probably
  ** not worth the effort.  Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
  */
  if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
    return 0;
  }
#endif




  /* If we get this far, it means that the xfer optimization is at
  ** least a possibility, though it might only work if the destination
  ** table (tab1) is initially empty.
  */
#ifdef SQLITE_TEST
  sqlite4_xferopt_count++;

Added src/kvlsm.c.

































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
299
300
301
302
303
304
305
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
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
/*
** 2012 January 20
**
** 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.
**
*************************************************************************
**
** An in-memory key/value storage subsystem that presents the interfadce
** defined by storage.h
*/
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_LSM
#include "lsm.h"

typedef struct KVLsm KVLsm;
typedef struct KVLsmCsr KVLsmCsr;

struct KVLsm {
  KVStore base;                   /* Base class, must be first */
  lsm_db *pDb;                    /* LSM database handle */
  lsm_cursor *pCsr;               /* LSM cursor holding read-trans open */
};

struct KVLsmCsr {
  KVCursor base;                  /* Base class. Must be first */
  lsm_cursor *pCsr;               /* LSM cursor handle */
};

#define MAX(x,y) (((x)>(y)) ? (x) : (y))
  
/*
** Begin a transaction or subtransaction.
**
** If iLevel==1 then begin an outermost read transaction.
**
** If iLevel==2 then begin an outermost write transaction.
**
** If iLevel>2 then begin a nested write transaction.
**
** iLevel may not be less than 1.  After this routine returns successfully
** the transaction level will be equal to iLevel.  The transaction level
** must be at least 1 to read and at least 2 to write.
*/
static int kvlsmBegin(KVStore *pKVStore, int iLevel){
  int rc = SQLITE_OK;
  KVLsm *p = (KVLsm *)pKVStore;

  assert( iLevel>0 );
  if( p->pCsr==0 ){
    rc = lsm_csr_open(p->pDb, &p->pCsr);
  }
  if( rc==SQLITE_OK && iLevel>=2 && iLevel>=pKVStore->iTransLevel ){
    rc = lsm_begin(p->pDb, iLevel-1);
  }

  if( rc==SQLITE_OK ){
    pKVStore->iTransLevel = MAX(iLevel, pKVStore->iTransLevel);
  }else if( pKVStore->iTransLevel==0 ){
    lsm_csr_close(p->pCsr);
    p->pCsr = 0;
  }

  return rc;
}

/*
** Commit a transaction or subtransaction.
**
** Make permanent all changes back through the most recent xBegin 
** with the iLevel+1.  If iLevel==0 then make all changes permanent.
** The argument iLevel will always be less than the current transaction
** level when this routine is called.
**
** Commit is divided into two phases.  A rollback is still possible after
** phase one completes.  In this implementation, phase one is a no-op since
** phase two cannot fail.
**
** After this routine returns successfully, the transaction level will be 
** equal to iLevel.
*/
static int kvlsmCommitPhaseOne(KVStore *pKVStore, int iLevel){
  return SQLITE_OK;
}
static int kvlsmCommitPhaseTwo(KVStore *pKVStore, int iLevel){
  int rc = SQLITE_OK;
  KVLsm *p = (KVLsm *)pKVStore;

  if( pKVStore->iTransLevel>iLevel ){
    if( pKVStore->iTransLevel>=2 ){
      rc = lsm_commit(p->pDb, MAX(1, iLevel));
    }
    if( iLevel==0 ){
      lsm_csr_close(p->pCsr);
      p->pCsr = 0;
    }
    if( rc==SQLITE_OK ){
      pKVStore->iTransLevel = iLevel;
    }
  }
  return rc;
}

/*
** Rollback a transaction or subtransaction.
**
** Revert all uncommitted changes back through the most recent xBegin or 
** xCommit with the same iLevel.  If iLevel==0 then back out all uncommited
** changes.
**
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvlsmRollback(KVStore *pKVStore, int iLevel){
  int rc = SQLITE_OK;
  KVLsm *p = (KVLsm *)pKVStore;

  if( pKVStore->iTransLevel>iLevel ){
    if( pKVStore->iTransLevel>=2 ){
      rc = lsm_rollback(p->pDb, MAX(1, iLevel));
    }
    if( iLevel==0 ){
      lsm_csr_close(p->pCsr);
      p->pCsr = 0;
    }
    if( rc==SQLITE_OK ){
      pKVStore->iTransLevel = iLevel;
    }
  }
  return rc;
}

/*
** Revert a transaction back to what it was when it started.
*/
static int kvlsmRevert(KVStore *pKVStore, int iLevel){
  return SQLITE_OK;
}

/*
** Implementation of the xReplace(X, aKey, nKey, aData, nData) method.
**
** Insert or replace the entry with the key aKey[0..nKey-1].  The data for
** the new entry is aData[0..nData-1].  Return SQLITE_OK on success or an
** error code if the insert fails.
**
** The inputs aKey[] and aData[] are only valid until this routine
** returns.  If the storage engine needs to keep that information
** long-term, it will need to make its own copy of these values.
**
** A transaction will always be active when this routine is called.
*/
static int kvlsmReplace(
  KVStore *pKVStore,
  const KVByteArray *aKey, KVSize nKey,
  const KVByteArray *aData, KVSize nData
){
  KVLsm *p = (KVLsm *)pKVStore;
  return lsm_write(p->pDb, (void *)aKey, nKey, (void *)aData, nData);
}

/*
** Create a new cursor object.
*/
static int kvlsmOpenCursor(KVStore *pKVStore, KVCursor **ppKVCursor){
  int rc = SQLITE_OK;
  KVLsm *p = (KVLsm *)pKVStore;
  KVLsmCsr *pCsr;

  pCsr = (KVLsmCsr *)sqlite4_malloc(sizeof(KVLsmCsr));
  if( pCsr==0 ){
    rc = SQLITE_NOMEM;
  }else{
    memset(pCsr, 0, sizeof(KVLsmCsr));
    rc = lsm_csr_open(p->pDb, &pCsr->pCsr);

    if( rc==SQLITE_OK ){
      pCsr->base.pStore = pKVStore;
      pCsr->base.pStoreVfunc = pKVStore->pStoreVfunc;
    }else{
      sqlite4_free(pCsr);
      pCsr = 0;
    }
  }

  *ppKVCursor = (KVCursor*)pCsr;
  return rc;
}

/*
** Reset a cursor
*/
static int kvlsmReset(KVCursor *pKVCursor){
  return SQLITE_OK;
}

/*
** Destroy a cursor object
*/
static int kvlsmCloseCursor(KVCursor *pKVCursor){
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
  lsm_csr_close(pCsr->pCsr);
  sqlite4_free(pCsr);
  return SQLITE_OK;
}

/*
** Move a cursor to the next non-deleted node.
*/
static int kvlsmNextEntry(KVCursor *pKVCursor){
  int rc;
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
  rc = lsm_csr_next(pCsr->pCsr);
  if( rc==SQLITE_OK && lsm_csr_valid(pCsr->pCsr)==0 ){
    rc = SQLITE_NOTFOUND;
  }
  return rc;
}

/*
** Move a cursor to the previous non-deleted node.
*/
static int kvlsmPrevEntry(KVCursor *pKVCursor){
  int rc;
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
  rc = lsm_csr_prev(pCsr->pCsr);
  if( rc==SQLITE_OK && lsm_csr_valid(pCsr->pCsr)==0 ){
    rc = SQLITE_NOTFOUND;
  }
  return rc;
}

/*
** Seek a cursor.
*/
static int kvlsmSeek(
  KVCursor *pKVCursor, 
  const KVByteArray *aKey,
  KVSize nKey,
  int dir
){
  int rc;
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;

  assert( dir==0 || dir==1 || dir==-1 );
  assert( LSM_SEEK_EQ==0 && LSM_SEEK_GE==1 && LSM_SEEK_LE==-1 );

  rc = lsm_csr_seek(pCsr->pCsr, (void *)aKey, nKey, dir);
  if( rc==SQLITE_OK ){
    if( lsm_csr_valid(pCsr->pCsr)==0 ){
      rc = SQLITE_NOTFOUND;
    }else{
      void *pDbKey;
      int nDbKey;

      rc = lsm_csr_key(pCsr->pCsr, &pDbKey, &nDbKey);
      if( rc==SQLITE_OK && (nDbKey!=nKey || memcmp(pDbKey, aKey, nKey)) ){
        rc = SQLITE_INEXACT;
      }
    }
  }

  return rc;
}

/*
** Delete the entry that the cursor is pointing to.
**
** Though the entry is "deleted", it still continues to exist as a
** phantom.  Subsequent xNext or xPrev calls will work, as will
** calls to xKey and xData, thought the result from xKey and xData
** are undefined.
*/
static int kvlsmDelete(KVCursor *pKVCursor){
  int rc;
  void *pKey;
  int nKey;
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;

  assert( lsm_csr_valid(pCsr->pCsr) );
  rc = lsm_csr_key(pCsr->pCsr, &pKey, &nKey);
  if( rc==SQLITE_OK ){
    rc = lsm_delete(((KVLsm *)(pKVCursor->pStore))->pDb, pKey, nKey);
  }

  return SQLITE_OK;
}

/*
** Return the key of the node the cursor is pointing to.
*/
static int kvlsmKey(
  KVCursor *pKVCursor,         /* The cursor whose key is desired */
  const KVByteArray **paKey,   /* Make this point to the key */
  KVSize *pN                   /* Make this point to the size of the key */
){
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;

  assert( lsm_csr_valid(pCsr->pCsr) );
  return lsm_csr_key(pCsr->pCsr, (void **)paKey, (int *)pN);
}

/*
** Return the data of the node the cursor is pointing to.
*/
static int kvlsmData(
  KVCursor *pKVCursor,         /* The cursor from which to take the data */
  KVSize ofst,                 /* Offset into the data to begin reading */
  KVSize n,                    /* Number of bytes requested */
  const KVByteArray **paData,  /* Pointer to the data written here */
  KVSize *pNData               /* Number of bytes delivered */
){
  KVLsmCsr *pCsr = (KVLsmCsr *)pKVCursor;
  int rc;
  void *pData;
  int nData;

  rc = lsm_csr_value(pCsr->pCsr, &pData, &nData);
  if( rc==SQLITE_OK ){
    if( n<0 ){
      *paData = pData;
      *pNData = nData;
    }else{
      int nOut = n;
      if( (ofst+n)> nData ) nOut = nData - ofst;
      if( nOut<0 ) nOut = 0;

      *paData = &((u8 *)pData)[n];
      *pNData = nOut;
    }
  }

  return rc;
}

/*
** Destructor for the entire in-memory storage tree.
*/
static int kvlsmClose(KVStore *pKVStore){
  KVLsm *p = (KVLsm *)pKVStore;

  /* If there is an active transaction, roll it back. The important
  ** part is that the read-transaction cursor is closed. Otherwise, the
  ** call to lsm_close() below will fail.  */
  kvlsmRollback(pKVStore, 0);
  assert( p->pCsr==0 );

  lsm_close(p->pDb);
  sqlite4_free(p);
  return SQLITE_OK;
}

/*
** Create a new in-memory storage engine and return a pointer to it.
*/
int sqlite4KVStoreOpenLsm(
  KVStore **ppKVStore,
  const char *zName,
  unsigned openFlags
){

  /* Virtual methods for an LSM data store */
  static const KVStoreMethods kvlsmMethods = {
    kvlsmReplace,
    kvlsmOpenCursor,
    kvlsmSeek,
    kvlsmNextEntry,
    kvlsmPrevEntry,
    kvlsmDelete,
    kvlsmKey,
    kvlsmData,
    kvlsmReset,
    kvlsmCloseCursor,
    kvlsmBegin,
    kvlsmCommitPhaseOne,
    kvlsmCommitPhaseTwo,
    kvlsmRollback,
    kvlsmRevert,
    kvlsmClose
  };

  KVLsm *pNew;
  int rc = SQLITE_OK;

  pNew = (KVLsm *)sqlite4_malloc(sizeof(KVLsm));
  if( pNew==0 ){
    rc = SQLITE_NOMEM;
  }else{
    memset(pNew, 0, sizeof(KVLsm));
    pNew->base.pStoreVfunc = &kvlsmMethods;

    rc = lsm_new(&pNew->pDb);
    if( rc==SQLITE_OK ){
      rc = lsm_open(pNew->pDb, zName);
    }

    if( rc!=SQLITE_OK ){
      lsm_close(pNew->pDb);
      sqlite4_free(pNew);
      pNew = 0;
    }
  }

  *ppKVStore = (KVStore*)pNew;
  return rc;
}

#endif /* SQLITE_ENABLE_LSM */



Changes to src/kvmem.c.

146
147
148
149
150
151
152

153
154
155
156
157
158
159
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
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
...
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
...
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
...
627
628
629
630
631
632
633










































634
635
636
637
638
639
640
...
673
674
675
676
677
678
679

















680
681
682
683

684
685
686
687
688
689
690
...
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
765
766
767
...
846
847
848
849
850
851
852
853




854
855
856
857
858
859
860
861
862

/*
** Return a pointer to the pBefore or pAfter pointer in the parent
** of p that points to p.  Or if p is the root node, return pp.
*/
static KVMemNode **kvmemFromPtr(KVMemNode *p, KVMemNode **pp){
  KVMemNode *pUp = p->pUp;
  if( pUp==0 ) return pp;

  if( pUp->pAfter==p ) return &pUp->pAfter;
  return &pUp->pBefore;
}

/*
** Rebalance all nodes starting with p and working up to the root.
** Return the new root.
................................................................................
*/
static int kvmemKeyCompare(
  const KVByteArray *aK1, KVSize nK1,
  const KVByteArray *aK2, KVSize nK2
){
  int c;
  c = memcmp(aK1, aK2, nK1<nK2 ? nK1 : nK2);
  if( c==0 ) c = nK2 - nK1;
  return c;
}

/*
** Create a new KVMemData object
*/
static KVMemData *kvmemDataNew(const KVByteArray *aData, KVSize nData){
................................................................................
    memcpy(pNode->aKey, aKey, nKey);
    pNode->nKey = nKey;
    pNode->nRef = 1;
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ){
      sqlite4_free(pNode);
      pNode = 0;
    }else{

      pChng->pData = 0;
    }

  }













  return pNode;
}


















/* Remove node pOld from the tree.  pOld must be an element of the tree.
*/
static void kvmemRemoveNode(KVMem *p, KVMemNode *pOld){
  KVMemNode **ppParent;
  KVMemNode *pBalance;

  kvmemDataUnref(pOld->pData);
  pOld->pData = 0;
  ppParent = kvmemFromPtr(pOld, &p->pRoot);
  if( pOld->pBefore==0 && pOld->pAfter==0 ){
    *ppParent = 0;
    pBalance = pOld->pUp;
  }else if( pOld->pBefore && pOld->pAfter ){
    KVMemNode *pX, *pY;

    pX = kvmemFirst(pOld->pAfter);




    *kvmemFromPtr(pX, 0) = 0;

    pBalance = pX->pUp;
    pX->pAfter = pOld->pAfter;
    if( pX->pAfter ){
      pX->pAfter->pUp = pX;
    }else{
      assert( pBalance==pOld );
      pBalance = pX;

    }
    pX->pBefore = pY = pOld->pBefore;
    if( pY ) pY->pUp = pX;
    pX->pUp = pOld->pUp;
    *ppParent = pX;
  }else if( pOld->pBefore==0 ){
    *ppParent = pBalance = pOld->pAfter;
    pBalance->pUp = pOld->pUp;
  }else if( pOld->pAfter==0 ){
    *ppParent = pBalance = pOld->pBefore;
    pBalance->pUp = pOld->pUp;
  }

  p->pRoot = kvmemBalance(pBalance);

  kvmemNodeUnref(pOld);
}

/*
** End of low-level access routines
***************************************************************************
** Interface routines follow
................................................................................
  return SQLITE_OK;
}
static int kvmemCommitPhaseTwo(KVStore *pKVStore, int iLevel){
  KVMem *p = (KVMem*)pKVStore;
  assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
  assert( iLevel>=0 );
  assert( iLevel<p->base.iTransLevel );

  while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
    KVMemChng *pChng, *pNext;


    for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
      KVMemNode *pNode = pChng->pNode;
      if( pNode->pData ){
        pNode->mxTrans = pChng->oldTrans;
      }else{
        kvmemRemoveNode(p, pNode);
      }
      kvmemDataUnref(pChng->pData);
      pNext = pChng->pNext;
      sqlite4_free(pChng);
    }
















    p->apLog[p->base.iTransLevel-2] = 0;
    p->base.iTransLevel--;
  }

  p->base.iTransLevel = iLevel;
  return SQLITE_OK;
}

/*
** Rollback a transaction or subtransaction.
**
................................................................................
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvmemRollback(KVStore *pKVStore, int iLevel){
  KVMem *p = (KVMem*)pKVStore;
  assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
  assert( iLevel>=0 );
  assert( iLevel<p->base.iTransLevel );
  while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
    KVMemChng *pChng, *pNext;
    for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
      KVMemNode *pNode = pChng->pNode;
      if( pChng->pData ){
        kvmemDataUnref(pNode->pData);
        pNode->pData = pChng->pData;
        pNode->mxTrans = pChng->oldTrans;
      }else{
        kvmemRemoveNode(p, pNode);
      }
      pNext = pChng->pNext;
................................................................................
    pCur->pOwner->nCursor--;
    kvmemReset(pKVCursor);
    memset(pCur, 0, sizeof(*pCur));
    sqlite4_free(pCur);
  }
  return SQLITE_OK;
}











































/*
** Seek a cursor.
*/
static int kvmemSeek(
  KVCursor *pKVCursor, 
  const KVByteArray *aKey,
................................................................................
    }
  }
  kvmemNodeUnref(pCur->pNode);
  kvmemDataUnref(pCur->pData);
  if( pBest ){
    pCur->pNode = kvmemNodeRef(pBest);
    pCur->pData = kvmemDataRef(pBest->pData);

















  }else{
    pCur->pNode = 0;
    pCur->pData = 0;
  }

  return rc;
}

/*
** Delete the entry that the cursor is pointing to.
**
** Though the entry is "deleted", it still continues to exist as a
................................................................................
  assert( p->base.iTransLevel>=2 );
  pNode = pCur->pNode;
  if( pNode==0 ) return SQLITE_OK;
  if( pNode->pData==0 ) return SQLITE_OK;
  if( pNode->mxTrans<p->base.iTransLevel ){
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ) return SQLITE_NOMEM;

  }else{
    kvmemDataUnref(pNode->pData);
    pNode->pData = 0;
  }
  return SQLITE_OK;
}

/*
** Move a cursor to the next non-deleted node.
*/
static int kvmemNextEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemNext(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Move a cursor to the previous non-deleted node.
*/
static int kvmemPrevEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemPrev(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Return the key of the node the cursor is pointing to.
*/
static int kvmemKey(
  KVCursor *pKVCursor,         /* The cursor whose key is desired */
  const KVByteArray **paKey,   /* Make this point to the key */
  KVSize *pN                   /* Make this point to the size of the key */
................................................................................
  kvmemRevert,
  kvmemClose
};

/*
** Create a new in-memory storage engine and return a pointer to it.
*/
int sqlite4KVStoreOpenMem(KVStore **ppKVStore, unsigned openFlags){




  KVMem *pNew = sqlite4_malloc( sizeof(*pNew) );
  if( pNew==0 ) return SQLITE_NOMEM;
  memset(pNew, 0, sizeof(*pNew));
  pNew->base.pStoreVfunc = &kvmemMethods;
  pNew->iMagicKVMemBase = SQLITE_KVMEMBASE_MAGIC;
  pNew->openFlags = openFlags;
  *ppKVStore = (KVStore*)pNew;
  return SQLITE_OK;
}








>







 







|







 







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


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



|
|
<







|
>

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












>

>







 







>


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



>







 







<




|







 







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







 







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




>







 







>







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







 







|
>
>
>
>









>
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
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
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
...
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
...
530
531
532
533
534
535
536

537
538
539
540
541
542
543
544
545
546
547
548
...
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
...
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
...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838










































839
840
841
842
843
844
845
...
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
/*
** Return a pointer to the pBefore or pAfter pointer in the parent
** of p that points to p.  Or if p is the root node, return pp.
*/
static KVMemNode **kvmemFromPtr(KVMemNode *p, KVMemNode **pp){
  KVMemNode *pUp = p->pUp;
  if( pUp==0 ) return pp;
  assert( pUp->pAfter==p || pUp->pBefore==p );
  if( pUp->pAfter==p ) return &pUp->pAfter;
  return &pUp->pBefore;
}

/*
** Rebalance all nodes starting with p and working up to the root.
** Return the new root.
................................................................................
*/
static int kvmemKeyCompare(
  const KVByteArray *aK1, KVSize nK1,
  const KVByteArray *aK2, KVSize nK2
){
  int c;
  c = memcmp(aK1, aK2, nK1<nK2 ? nK1 : nK2);
  if( c==0 ) c = nK1 - nK2;
  return c;
}

/*
** Create a new KVMemData object
*/
static KVMemData *kvmemDataNew(const KVByteArray *aData, KVSize nData){
................................................................................
    memcpy(pNode->aKey, aKey, nKey);
    pNode->nKey = nKey;
    pNode->nRef = 1;
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ){
      sqlite4_free(pNode);
      pNode = 0;

    }
    assert( pChng==0 || pChng->pData==0 );
  }
  return pNode;
}

#ifdef SQLITE_DEBUG
/*
** Return the number of times that node pNode occurs in the sub-tree 
** headed by node pSub. This is used to assert() that no node structure
** is linked into the tree more than once.
*/
static int countNodeOccurences(KVMemNode *pSub, KVMemNode *pNode){
  int iRet = (pSub==pNode);
  if( pSub ){
    iRet += countNodeOccurences(pSub->pBefore, pNode);
    iRet += countNodeOccurences(pSub->pAfter, pNode);
  }
  return iRet;
}

/*
** Check that all the pUp pointers in the sub-tree headed by pSub are
** correct. Fail an assert if this is not the case.
*/
static void assertUpPointers(KVMemNode *pSub){
  if( pSub ){
    assert( pSub->pBefore==0 || pSub->pBefore->pUp==pSub );
    assert( pSub->pAfter==0 || pSub->pAfter->pUp==pSub );
    assertUpPointers(pSub->pBefore);
    assertUpPointers(pSub->pAfter);
  }
}

#else
#define assertUpPointers(x)
#endif

/* Remove node pOld from the tree.  pOld must be an element of the tree.
*/
static void kvmemRemoveNode(KVMem *p, KVMemNode *pOld){
  KVMemNode **ppParent;           /* Location of pointer to pOld */
  KVMemNode *pBalance;            /* Node to run kvmemBalance() on */

  kvmemDataUnref(pOld->pData);
  pOld->pData = 0;
  ppParent = kvmemFromPtr(pOld, &p->pRoot);
  if( pOld->pBefore==0 && pOld->pAfter==0 ){
    *ppParent = 0;
    pBalance = pOld->pUp;
  }else if( pOld->pBefore && pOld->pAfter ){
    KVMemNode *pX;                /* Smallest node that is larger than pOld */
    KVMemNode *pY;                /* Left-hand child of pOld */
    pX = kvmemFirst(pOld->pAfter);
    assert( pX->pBefore==0 );
    if( pX==pOld->pAfter ){
      pBalance = pX;
    }else{
      *kvmemFromPtr(pX, 0) = pX->pAfter;
      if( pX->pAfter ) pX->pAfter->pUp = pX->pUp;
      pBalance = pX->pUp;
      pX->pAfter = pOld->pAfter;
      if( pX->pAfter ){
        pX->pAfter->pUp = pX;
      }else{
        assert( pBalance==pOld );
        pBalance = pX;
      }
    }
    pX->pBefore = pY = pOld->pBefore;
    if( pY ) pY->pUp = pX;
    pX->pUp = pOld->pUp;
    *ppParent = pX;
  }else if( pOld->pBefore==0 ){
    *ppParent = pBalance = pOld->pAfter;
    pBalance->pUp = pOld->pUp;
  }else if( pOld->pAfter==0 ){
    *ppParent = pBalance = pOld->pBefore;
    pBalance->pUp = pOld->pUp;
  }
  assertUpPointers(p->pRoot);
  p->pRoot = kvmemBalance(pBalance);
  assertUpPointers(p->pRoot);
  kvmemNodeUnref(pOld);
}

/*
** End of low-level access routines
***************************************************************************
** Interface routines follow
................................................................................
  return SQLITE_OK;
}
static int kvmemCommitPhaseTwo(KVStore *pKVStore, int iLevel){
  KVMem *p = (KVMem*)pKVStore;
  assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
  assert( iLevel>=0 );
  assert( iLevel<p->base.iTransLevel );
  assertUpPointers(p->pRoot);
  while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
    KVMemChng *pChng, *pNext;

    if( iLevel<2 ){
      for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
        KVMemNode *pNode = pChng->pNode;
        if( pNode->pData ){
          pNode->mxTrans = pChng->oldTrans;
        }else{
          kvmemRemoveNode(p, pNode);
        }
        kvmemDataUnref(pChng->pData);
        pNext = pChng->pNext;
        sqlite4_free(pChng);
      }
    }else{
      KVMemChng **pp;
      int iFrom = p->base.iTransLevel-2;
      int iTo = p->base.iTransLevel-3;
      assert( iTo>=0 );

      for(pp=&p->apLog[iFrom]; *pp; pp=&((*pp)->pNext)){
        assert( (*pp)->pNode->mxTrans==p->base.iTransLevel 
             || (*pp)->pNode->mxTrans==(p->base.iTransLevel-1)
        );
        (*pp)->pNode->mxTrans = p->base.iTransLevel - 1;
      }
      *pp = p->apLog[iTo];
      p->apLog[iTo] = p->apLog[iFrom];
    }

    p->apLog[p->base.iTransLevel-2] = 0;
    p->base.iTransLevel--;
  }
  assertUpPointers(p->pRoot);
  p->base.iTransLevel = iLevel;
  return SQLITE_OK;
}

/*
** Rollback a transaction or subtransaction.
**
................................................................................
** After this routine returns successfully, the transaction level will be
** equal to iLevel.
*/
static int kvmemRollback(KVStore *pKVStore, int iLevel){
  KVMem *p = (KVMem*)pKVStore;
  assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
  assert( iLevel>=0 );

  while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
    KVMemChng *pChng, *pNext;
    for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
      KVMemNode *pNode = pChng->pNode;
      if( pChng->pData || pChng->oldTrans>0 ){
        kvmemDataUnref(pNode->pData);
        pNode->pData = pChng->pData;
        pNode->mxTrans = pChng->oldTrans;
      }else{
        kvmemRemoveNode(p, pNode);
      }
      pNext = pChng->pNext;
................................................................................
    pCur->pOwner->nCursor--;
    kvmemReset(pKVCursor);
    memset(pCur, 0, sizeof(*pCur));
    sqlite4_free(pCur);
  }
  return SQLITE_OK;
}

/*
** Move a cursor to the next non-deleted node.
*/
static int kvmemNextEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemNext(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Move a cursor to the previous non-deleted node.
*/
static int kvmemPrevEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemPrev(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Seek a cursor.
*/
static int kvmemSeek(
  KVCursor *pKVCursor, 
  const KVByteArray *aKey,
................................................................................
    }
  }
  kvmemNodeUnref(pCur->pNode);
  kvmemDataUnref(pCur->pData);
  if( pBest ){
    pCur->pNode = kvmemNodeRef(pBest);
    pCur->pData = kvmemDataRef(pBest->pData);

    /* The cursor currently points to a deleted node. If parameter 'direction'
    ** was zero (exact matches only), then the search has failed - return
    ** SQLITE_NOTFOUND. Otherwise, advance to the next (if direction is +ve)
    ** or the previous (if direction is -ve) undeleted node in the tree.  */
    if( pCur->pData==0 ){
      if( direction==0 ){
        rc = SQLITE_NOTFOUND;
      }else{ 
        if( (direction>0 ? kvmemNextEntry : kvmemPrevEntry)(pCur) ){
          rc = SQLITE_NOTFOUND;
        }else{
          rc = SQLITE_INEXACT;
        }
      }
    }

  }else{
    pCur->pNode = 0;
    pCur->pData = 0;
  }
  assert( rc!=SQLITE_DONE );
  return rc;
}

/*
** Delete the entry that the cursor is pointing to.
**
** Though the entry is "deleted", it still continues to exist as a
................................................................................
  assert( p->base.iTransLevel>=2 );
  pNode = pCur->pNode;
  if( pNode==0 ) return SQLITE_OK;
  if( pNode->pData==0 ) return SQLITE_OK;
  if( pNode->mxTrans<p->base.iTransLevel ){
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ) return SQLITE_NOMEM;
    assert( pNode->pData==0 );
  }else{
    kvmemDataUnref(pNode->pData);
    pNode->pData = 0;
  }
  return SQLITE_OK;
}











































/*
** Return the key of the node the cursor is pointing to.
*/
static int kvmemKey(
  KVCursor *pKVCursor,         /* The cursor whose key is desired */
  const KVByteArray **paKey,   /* Make this point to the key */
  KVSize *pN                   /* Make this point to the size of the key */
................................................................................
  kvmemRevert,
  kvmemClose
};

/*
** Create a new in-memory storage engine and return a pointer to it.
*/
int sqlite4KVStoreOpenMem(
  KVStore **ppKVStore, 
  const char *zName,
  unsigned openFlags
){
  KVMem *pNew = sqlite4_malloc( sizeof(*pNew) );
  if( pNew==0 ) return SQLITE_NOMEM;
  memset(pNew, 0, sizeof(*pNew));
  pNew->base.pStoreVfunc = &kvmemMethods;
  pNew->iMagicKVMemBase = SQLITE_KVMEMBASE_MAGIC;
  pNew->openFlags = openFlags;
  *ppKVStore = (KVStore*)pNew;
  return SQLITE_OK;
}

Changes to src/main.c.

274
275
276
277
278
279
280












281
282
283
284
285
286
287

  /* sqlite4_config() shall return SQLITE_MISUSE if it is invoked while
  ** the SQLite library is in use. */
  if( sqlite4GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;

  va_start(ap, op);
  switch( op ){













    /* Mutex configuration options are only available in a threadsafe
    ** compile. 
    */
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
    case SQLITE_CONFIG_SINGLETHREAD: {
      /* Disable all mutexing */







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







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

  /* sqlite4_config() shall return SQLITE_MISUSE if it is invoked while
  ** the SQLite library is in use. */
  if( sqlite4GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;

  va_start(ap, op);
  switch( op ){
    case SQLITE_CONFIG_SET_KVFACTORY: {
      sqlite4GlobalConfig.xKVFile = *va_arg(ap, 
          int (*)(KVStore **, const char *, unsigned int)
      );
      break;
    }

    case SQLITE_CONFIG_GET_KVFACTORY: {
      *va_arg(ap, int (**)(KVStore **, const char *, unsigned int)) =
          sqlite4GlobalConfig.xKVFile;
      break;
    }

    /* Mutex configuration options are only available in a threadsafe
    ** compile. 
    */
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
    case SQLITE_CONFIG_SINGLETHREAD: {
      /* Disable all mutexing */

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
703
704
705
  **
  ** 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;

        /* Do nothing for views */
        if( IsView(pTab) ) continue;

        /* 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/resolve.c.

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
              if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
            }
            cnt++;
            pExpr->iTable = pItem->iCursor;
            pExpr->pTab = pTab;
            pMatch = pItem;
            pSchema = pTab->pSchema;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
            break;
          }
        }
      }
    }

#ifndef SQLITE_OMIT_TRIGGER
................................................................................
      if( pTab ){ 
        int iCol;
        pSchema = pTab->pSchema;
        cntTab++;
        for(iCol=0; iCol<pTab->nCol; iCol++){
          Column *pCol = &pTab->aCol[iCol];
          if( sqlite4StrICmp(pCol->zName, zCol)==0 ){
            if( iCol==pTab->iPKey ){
              iCol = -1;
            }
            break;
          }
        }
        if( iCol>=pTab->nCol && sqlite4IsRowid(zCol) ){
          iCol = -1;        /* IMP: R-44911-55124 */
        }
        if( iCol<pTab->nCol ){
................................................................................
*/
Expr *sqlite4CreateColumnExpr(sqlite4 *db, SrcList *pSrc, int iSrc, int iCol){
  Expr *p = sqlite4ExprAlloc(db, TK_COLUMN, 0, 0);
  if( p ){
    struct SrcList_item *pItem = &pSrc->a[iSrc];
    p->pTab = pItem->pTab;
    p->iTable = pItem->iCursor;
    if( p->pTab->iPKey==iCol ){
      p->iColumn = -1;
    }else{
      p->iColumn = (ynVar)iCol;
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );
      pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
    }
    ExprSetProperty(p, EP_Resolved);
  }
  return p;
}

/*
** This routine is callback for sqlite4WalkExpr().







<
|







 







<
<
<







 







<
<
<
|
|
|
|
<







216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
...
246
247
248
249
250
251
252



253
254
255
256
257
258
259
...
409
410
411
412
413
414
415



416
417
418
419

420
421
422
423
424
425
426
              if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
            }
            cnt++;
            pExpr->iTable = pItem->iCursor;
            pExpr->pTab = pTab;
            pMatch = pItem;
            pSchema = pTab->pSchema;

            pExpr->iColumn = (i16)j;
            break;
          }
        }
      }
    }

#ifndef SQLITE_OMIT_TRIGGER
................................................................................
      if( pTab ){ 
        int iCol;
        pSchema = pTab->pSchema;
        cntTab++;
        for(iCol=0; iCol<pTab->nCol; iCol++){
          Column *pCol = &pTab->aCol[iCol];
          if( sqlite4StrICmp(pCol->zName, zCol)==0 ){



            break;
          }
        }
        if( iCol>=pTab->nCol && sqlite4IsRowid(zCol) ){
          iCol = -1;        /* IMP: R-44911-55124 */
        }
        if( iCol<pTab->nCol ){
................................................................................
*/
Expr *sqlite4CreateColumnExpr(sqlite4 *db, SrcList *pSrc, int iSrc, int iCol){
  Expr *p = sqlite4ExprAlloc(db, TK_COLUMN, 0, 0);
  if( p ){
    struct SrcList_item *pItem = &pSrc->a[iSrc];
    p->pTab = pItem->pTab;
    p->iTable = pItem->iCursor;



    p->iColumn = (ynVar)iCol;
    testcase( iCol==BMS );
    testcase( iCol==BMS-1 );
    pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);

    ExprSetProperty(p, EP_Resolved);
  }
  return p;
}

/*
** This routine is callback for sqlite4WalkExpr().

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/select.c.

410
411
412
413
414
415
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
...
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
...
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
...
958
959
960
961
962
963
964



965
966
967
968
969
970
971
972
973
974
975
976
977
978
...
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
....
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
....
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
....
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
....
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
....
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
....
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
....
3944
3945
3946
3947
3948
3949
3950
3951


3952
3953
3954
3955
3956
3957
3958
....
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
....
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
}

/*
** Insert code into "v" that will push the record on the top of the
** stack into the sorter.
*/
static void pushOntoSorter(
  Parse *pParse,         /* Parser context */
  ExprList *pOrderBy,    /* The ORDER BY clause */
  Select *pSelect,       /* The whole SELECT statement */
  int regData            /* Register holding data to be sorted */
){
  Vdbe *v = pParse->pVdbe;
  int nExpr = pOrderBy->nExpr;
  int regBase = sqlite4GetTempRange(pParse, nExpr+2);
  int regRecord = sqlite4GetTempReg(pParse);
  int regKey = sqlite4GetTempReg(pParse);
  int op;






  sqlite4ExprCacheClear(pParse);
  sqlite4ExprCodeExprList(pParse, pOrderBy, regBase, 0);
  sqlite4VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
  sqlite4ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);

  sqlite4VdbeAddOp2(v, OP_MakeKey, pOrderBy->iECursor, regKey);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);




  if( pSelect->selFlags & SF_UseSorter ){
    op = OP_SorterInsert;
  }else{
    op = OP_IdxInsert;
  }
  sqlite4VdbeAddOp3(v, op, pOrderBy->iECursor, regRecord, regKey);
  sqlite4ReleaseTempReg(pParse, regRecord);


  sqlite4ReleaseTempReg(pParse, regKey);
  sqlite4ReleaseTempRange(pParse, regBase, nExpr+2);

  if( pSelect->iLimit ){
    int addr1, addr2;
    int iLimit;
    if( pSelect->iOffset ){
      iLimit = pSelect->iOffset+1;
    }else{
      iLimit = pSelect->iLimit;
................................................................................
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc.  The calling
** function is responsible for seeing that this structure is eventually
** freed.  Add the KeyInfo structure to the P4 field of an opcode using
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
*/
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
  sqlite4 *db = pParse->db;
  int nExpr;
  KeyInfo *pInfo;
  struct ExprList_item *pItem;
  int i;








  nExpr = pList->nExpr;

  pInfo = sqlite4DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );

  if( pInfo ){


    pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
    pInfo->nField = (u16)nExpr;
    pInfo->enc = ENC(db);
    pInfo->db = db;
    for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){


      CollSeq *pColl;
      pColl = sqlite4ExprCollSeq(pParse, pItem->pExpr);
      if( !pColl ){
        pColl = db->pDfltColl;
      }
      pInfo->aColl[i] = pColl;
      pInfo->aSortOrder[i] = pItem->sortOrder;
    }
  }
  return pInfo;
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
................................................................................
#else
/* No-op versions of the explainXXX() functions and macros. */
# define explainComposite(v,w,x,y,z)
#endif

/*
** If the inner loop was generated using a non-null pOrderBy argument,
** then the results were placed in a sorter.  After the loop is terminated
** we need to run the sorter and output the results.  The following
** routine generates the code needed to do that.
*/
static void generateSortTail(
  Parse *pParse,    /* Parsing context */
  Select *p,        /* The SELECT statement */
  Vdbe *v,          /* Generate code into this VDBE */
  int nColumn,      /* Number of columns of data */
  SelectDest *pDest /* Write the sorted results here */
){
  int addrBreak = sqlite4VdbeMakeLabel(v);     /* Jump here to exit loop */
  int addrContinue = sqlite4VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;
  int iTab;
  int pseudoTab = 0;
  ExprList *pOrderBy = p->pOrderBy;

  int eDest = pDest->eDest;
  int iParm = pDest->iParm;

  int regRow;
  int regRowid;

  iTab = pOrderBy->iECursor;
  regRow = sqlite4GetTempReg(pParse);
  if( eDest==SRT_Output || eDest==SRT_Coroutine ){
    pseudoTab = pParse->nTab++;
    sqlite4VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
    regRowid = 0;
  }else{
    regRowid = sqlite4GetTempReg(pParse);
  }

  if( p->selFlags & SF_UseSorter ){
    int regSortOut = ++pParse->nMem;
    int ptab2 = pParse->nTab++;
    sqlite4VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
    addr = 1 + sqlite4VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    sqlite4VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
    sqlite4VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
    sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
  }else{
    addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    sqlite4VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
................................................................................
    }
#endif
    default: {
      int i;
      assert( eDest==SRT_Output || eDest==SRT_Coroutine ); 
      testcase( eDest==SRT_Output );
      testcase( eDest==SRT_Coroutine );



      for(i=0; i<nColumn; i++){
        assert( regRow!=pDest->iMem+i );
        sqlite4VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
        if( i==0 ){
          sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
        }
      }
      if( eDest==SRT_Output ){
        sqlite4VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
        sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
      break;
................................................................................
  sqlite4VdbeResolveLabel(v, addrContinue);
  if( p->selFlags & SF_UseSorter ){
    sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
  }else{
    sqlite4VdbeAddOp2(v, OP_Next, iTab, addr);
  }
  sqlite4VdbeResolveLabel(v, addrBreak);
  if( eDest==SRT_Output || eDest==SRT_Coroutine ){
    sqlite4VdbeAddOp2(v, OP_Close, pseudoTab, 0);
  }
}

/*
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
** The declaration type is the exact datatype definition extracted from the
................................................................................
          sNC.pNext = pNC;
          sNC.pParse = pNC->pParse;
          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
        }
      }else if( ALWAYS(pTab->pSchema) ){
        /* A real table */
        assert( !pS );
        if( iCol<0 ) iCol = pTab->iPKey;
        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
        if( iCol<0 ){
          zType = "INTEGER";
          zOriginCol = "rowid";
        }else{
          zType = pTab->aCol[iCol].zType;
          zOriginCol = pTab->aCol[iCol].zName;
................................................................................
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; ALWAYS(j<pTabList->nSrc); j++){
        if( pTabList->a[j].iCursor==p->iTable ) break;
      }
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      sqlite4VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
................................................................................
        pColExpr = pColExpr->pRight;
        assert( pColExpr!=0 );
      }
      if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
        /* For columns use the column name name */
        int iCol = pColExpr->iColumn;
        pTab = pColExpr->pTab;
        if( iCol<0 ) iCol = pTab->iPKey;
        zName = sqlite4MPrintf(db, "%s",
                 iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
      }else if( pColExpr->op==TK_ID ){
        assert( !ExprHasProperty(pColExpr, EP_IntValue) );
        zName = sqlite4MPrintf(db, "%s", pColExpr->u.zToken);
      }else{
        /* Use the original text of the column expression as its name */
................................................................................
  ** is disabled */
  assert( db->lookaside.bEnabled==0 );
  pTab->nRef = 1;
  pTab->zName = 0;
  pTab->nRowEst = 1000000;
  selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
  selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
  pTab->iPKey = -1;
  if( db->mallocFailed ){
    sqlite4DeleteTable(db, pTab);
    return 0;
  }
  return pTab;
}

................................................................................
      sqlite4WalkSelect(pWalker, pSel);
      pFrom->pTab = pTab = sqlite4DbMallocZero(db, sizeof(Table));
      if( pTab==0 ) return WRC_Abort;
      pTab->nRef = 1;
      pTab->zName = sqlite4MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
      while( pSel->pPrior ){ pSel = pSel->pPrior; }
      selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
      pTab->iPKey = -1;
      pTab->nRowEst = 1000000;
      pTab->tabFlags |= TF_Ephemeral;
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = 
................................................................................
      Expr *pE = pFunc->pExpr;
      assert( !ExprHasProperty(pE, EP_xIsSelect) );
      if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
        sqlite4ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
           "argument");
        pFunc->iDistinct = -1;
      }else{
        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
        sqlite4VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
                          (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
      }
    }
  }
}

................................................................................
  ** extracted in pre-sorted order.  If that is the case, then the
  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
  ** we figure out that the sorting index is not needed.  The addrSortIndex
  ** variable is used to facilitate that change.
  */
  if( pOrderBy ){
    KeyInfo *pKeyInfo;
    pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);


    pOrderBy->iECursor = pParse->nTab++;
    p->addrOpenEphm[2] = addrSortIndex =
      sqlite4VdbeAddOp4(v, OP_OpenEphemeral,
                           pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
                           (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
  }else{
    addrSortIndex = -1;
................................................................................
  }

  /* Open a virtual index to use for the distinct set.
  */
  if( p->selFlags & SF_Distinct ){
    KeyInfo *pKeyInfo;
    distinct = pParse->nTab++;
    pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
    addrDistinctIndex = sqlite4VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
        (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
  }else{
    distinct = addrDistinctIndex = -1;
  }

  /* Aggregate and non-aggregate queries are handled differently */
................................................................................

      /* If there is a GROUP BY clause we might need a sorting index to
      ** implement it.  Allocate that sorting index now.  If it turns out
      ** that we do not need it after all, the OP_SorterOpen instruction
      ** will be converted into a Noop.  
      */
      sAggInfo.sortingIdx = pParse->nTab++;
      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
      addrSortingIdx = sqlite4VdbeAddOp4(v, OP_SorterOpen, 
          sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
          0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);

      /* Initialize memory locations used by GROUP BY aggregate processing
      */
      iUseFlag = ++pParse->nMem;







|
|
|
|



|
<


>
>
>
>
>
>



<
>
|
|
>
>
>
>





|
<
>
>

|
>







 







|
|
<
<
|
|
>
>
>
>
>

>
>
|
>
|
>

>
>
|
|


<
>
>

|
<
|
<

|







 







|
|
|


|
|
|
|
|




|
<






|



|
<
<
<
<


>












|







 







>
>
>

<
|
<
<
|
|







 







<
<
<







 







<







 







<







 







<







 







<







 







<







 







|







 







|
>
>







 







|







 







|







410
411
412
413
414
415
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
...
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
...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
926
927
928
929




930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
...
973
974
975
976
977
978
979
980
981
982
983

984


985
986
987
988
989
990
991
992
993
....
1001
1002
1003
1004
1005
1006
1007



1008
1009
1010
1011
1012
1013
1014
....
1100
1101
1102
1103
1104
1105
1106

1107
1108
1109
1110
1111
1112
1113
....
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
....
1289
1290
1291
1292
1293
1294
1295

1296
1297
1298
1299
1300
1301
1302
....
1400
1401
1402
1403
1404
1405
1406

1407
1408
1409
1410
1411
1412
1413
....
3243
3244
3245
3246
3247
3248
3249

3250
3251
3252
3253
3254
3255
3256
....
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
....
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
....
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
....
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
}

/*
** Insert code into "v" that will push the record on the top of the
** stack into the sorter.
*/
static void pushOntoSorter(
  Parse *pParse,                  /* Parser context */
  ExprList *pOrderBy,             /* The ORDER BY clause */
  Select *pSelect,                /* The whole SELECT statement */
  int regData                     /* Register holding data to be sorted */
){
  Vdbe *v = pParse->pVdbe;
  int nExpr = pOrderBy->nExpr;
  int regBase = sqlite4GetTempRange(pParse, nExpr+1);

  int regKey = sqlite4GetTempReg(pParse);
  int op;

  /* Assemble the sort-key values in a contiguous array of registers
  ** starting at regBase. The sort-key consists of the result of each 
  ** expression in the ORDER BY clause followed by a unique sequence 
  ** number. The sequence number allows more than one row with the same
  ** sort-key.  */
  sqlite4ExprCacheClear(pParse);
  sqlite4ExprCodeExprList(pParse, pOrderBy, regBase, 0);
  sqlite4VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);


  /* Encode the sort-key. */
  sqlite4VdbeAddOp3(v, OP_MakeIdxKey, pOrderBy->iECursor, regBase, regKey);

  /* Insert an entry into the sorter. The key inserted is the encoded key
  ** created by the OP_MakeIdxKey coded above. The value is the record
  ** currently stored in register regData.  */
  if( pSelect->selFlags & SF_UseSorter ){
    op = OP_SorterInsert;
  }else{
    op = OP_IdxInsert;
  }
  sqlite4VdbeAddOp3(v, op, pOrderBy->iECursor, regData, regKey);


  /* Release the temporary registers */
  sqlite4ReleaseTempReg(pParse, regKey);
  sqlite4ReleaseTempRange(pParse, regBase, nExpr+1);

  if( pSelect->iLimit ){
    int addr1, addr2;
    int iLimit;
    if( pSelect->iOffset ){
      iLimit = pSelect->iOffset+1;
    }else{
      iLimit = pSelect->iLimit;
................................................................................
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc.  The calling
** function is responsible for seeing that this structure is eventually
** freed.  Add the KeyInfo structure to the P4 field of an opcode using
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
*/
static KeyInfo *keyInfoFromExprList(
  Parse *pParse, 


  ExprList *pList,
  int bOrderBy
){
  sqlite4 *db = pParse->db;       /* Database handle */
  int nField;                     /* Number of fields in keys */
  KeyInfo *pInfo;                 /* Object to return */
  int nByte;                      /* Bytes of space to allocate */

  assert( bOrderBy==0 || bOrderBy==1 );

  nField = pList->nExpr + bOrderBy;
  nByte = sizeof(KeyInfo) + nField * sizeof(CollSeq *) + nField;
  pInfo = (KeyInfo *)sqlite4DbMallocZero(db, nByte);

  if( pInfo ){
    int i;                        /* Used to iterate through pList */

    pInfo->aSortOrder = (u8*)&pInfo->aColl[nField];
    pInfo->nField = (u16)nField;
    pInfo->enc = ENC(db);
    pInfo->db = db;


    for(i=0; i<pList->nExpr; i++){
      CollSeq *pColl;
      pColl = sqlite4ExprCollSeq(pParse, pList->a[i].pExpr);

      if( !pColl ) pColl = db->pDfltColl;

      pInfo->aColl[i] = pColl;
      pInfo->aSortOrder[i] = pList->a[i].sortOrder;
    }
  }
  return pInfo;
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
................................................................................
#else
/* No-op versions of the explainXXX() functions and macros. */
# define explainComposite(v,w,x,y,z)
#endif

/*
** If the inner loop was generated using a non-null pOrderBy argument,
** then the results were placed in a sorter. After the loop is terminated
** we need to loop through the contents of the sorter and output the 
** results. The following routine generates the code needed to do that.
*/
static void generateSortTail(
  Parse *pParse,                  /* Parsing context */
  Select *p,                      /* The SELECT statement */
  Vdbe *v,                        /* Generate code into this VDBE */
  int nColumn,                    /* Number of columns of data */
  SelectDest *pDest               /* Write the sorted results here */
){
  int addrBreak = sqlite4VdbeMakeLabel(v);     /* Jump here to exit loop */
  int addrContinue = sqlite4VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;
  int iTab;                       /* Sorter object cursor */

  ExprList *pOrderBy = p->pOrderBy;

  int eDest = pDest->eDest;
  int iParm = pDest->iParm;

  int regRow;
  int regRowid = 0;

  iTab = pOrderBy->iECursor;
  regRow = sqlite4GetTempReg(pParse);
  if( eDest!=SRT_Output && eDest!=SRT_Coroutine ){




    regRowid = sqlite4GetTempReg(pParse);
  }

  if( p->selFlags & SF_UseSorter ){
    int regSortOut = ++pParse->nMem;
    int ptab2 = pParse->nTab++;
    sqlite4VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
    addr = 1 + sqlite4VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    sqlite4VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
    sqlite4VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
    sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
  }else{
    addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    /* sqlite4VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); */
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
................................................................................
    }
#endif
    default: {
      int i;
      assert( eDest==SRT_Output || eDest==SRT_Coroutine ); 
      testcase( eDest==SRT_Output );
      testcase( eDest==SRT_Coroutine );

      /* Read the data out of the sorter and into the array of nColumn
      ** contiguous registers starting at pDest->iMem.  */
      for(i=0; i<nColumn; i++){

        sqlite4VdbeAddOp3(v, OP_Column, iTab, i, pDest->iMem+i);


      }

      if( eDest==SRT_Output ){
        sqlite4VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
        sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
      break;
................................................................................
  sqlite4VdbeResolveLabel(v, addrContinue);
  if( p->selFlags & SF_UseSorter ){
    sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
  }else{
    sqlite4VdbeAddOp2(v, OP_Next, iTab, addr);
  }
  sqlite4VdbeResolveLabel(v, addrBreak);



}

/*
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
** The declaration type is the exact datatype definition extracted from the
................................................................................
          sNC.pNext = pNC;
          sNC.pParse = pNC->pParse;
          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
        }
      }else if( ALWAYS(pTab->pSchema) ){
        /* A real table */
        assert( !pS );

        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
        if( iCol<0 ){
          zType = "INTEGER";
          zOriginCol = "rowid";
        }else{
          zType = pTab->aCol[iCol].zType;
          zOriginCol = pTab->aCol[iCol].zName;
................................................................................
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; ALWAYS(j<pTabList->nSrc); j++){
        if( pTabList->a[j].iCursor==p->iTable ) break;
      }
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;

      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      sqlite4VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
................................................................................
        pColExpr = pColExpr->pRight;
        assert( pColExpr!=0 );
      }
      if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
        /* For columns use the column name name */
        int iCol = pColExpr->iColumn;
        pTab = pColExpr->pTab;

        zName = sqlite4MPrintf(db, "%s",
                 iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
      }else if( pColExpr->op==TK_ID ){
        assert( !ExprHasProperty(pColExpr, EP_IntValue) );
        zName = sqlite4MPrintf(db, "%s", pColExpr->u.zToken);
      }else{
        /* Use the original text of the column expression as its name */
................................................................................
  ** is disabled */
  assert( db->lookaside.bEnabled==0 );
  pTab->nRef = 1;
  pTab->zName = 0;
  pTab->nRowEst = 1000000;
  selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
  selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);

  if( db->mallocFailed ){
    sqlite4DeleteTable(db, pTab);
    return 0;
  }
  return pTab;
}

................................................................................
      sqlite4WalkSelect(pWalker, pSel);
      pFrom->pTab = pTab = sqlite4DbMallocZero(db, sizeof(Table));
      if( pTab==0 ) return WRC_Abort;
      pTab->nRef = 1;
      pTab->zName = sqlite4MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
      while( pSel->pPrior ){ pSel = pSel->pPrior; }
      selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);

      pTab->nRowEst = 1000000;
      pTab->tabFlags |= TF_Ephemeral;
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = 
................................................................................
      Expr *pE = pFunc->pExpr;
      assert( !ExprHasProperty(pE, EP_xIsSelect) );
      if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
        sqlite4ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
           "argument");
        pFunc->iDistinct = -1;
      }else{
        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0);
        sqlite4VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
                          (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
      }
    }
  }
}

................................................................................
  ** extracted in pre-sorted order.  If that is the case, then the
  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
  ** we figure out that the sorting index is not needed.  The addrSortIndex
  ** variable is used to facilitate that change.
  */
  if( pOrderBy ){
    KeyInfo *pKeyInfo;
    pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 1);
    if( pKeyInfo ) pKeyInfo->nData = pEList->nExpr;

    pOrderBy->iECursor = pParse->nTab++;
    p->addrOpenEphm[2] = addrSortIndex =
      sqlite4VdbeAddOp4(v, OP_OpenEphemeral,
                           pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
                           (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
  }else{
    addrSortIndex = -1;
................................................................................
  }

  /* Open a virtual index to use for the distinct set.
  */
  if( p->selFlags & SF_Distinct ){
    KeyInfo *pKeyInfo;
    distinct = pParse->nTab++;
    pKeyInfo = keyInfoFromExprList(pParse, p->pEList, 0);
    addrDistinctIndex = sqlite4VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
        (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
  }else{
    distinct = addrDistinctIndex = -1;
  }

  /* Aggregate and non-aggregate queries are handled differently */
................................................................................

      /* If there is a GROUP BY clause we might need a sorting index to
      ** implement it.  Allocate that sorting index now.  If it turns out
      ** that we do not need it after all, the OP_SorterOpen instruction
      ** will be converted into a Noop.  
      */
      sAggInfo.sortingIdx = pParse->nTab++;
      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0);
      addrSortingIdx = sqlite4VdbeAddOp4(v, OP_SorterOpen, 
          sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
          0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);

      /* Initialize memory locations used by GROUP BY aggregate processing
      */
      iUseFlag = ++pParse->nMem;

Changes to src/sqlite.h.in.

1529
1530
1531
1532
1533
1534
1535



1536
1537
1538
1539
1540
1541
1542
#define SQLITE_CONFIG_PCACHE       14  /* no-op */
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite4_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite4_pcache_methods2* */




/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite4_db_config()] interface.
**
** New configuration options may be added in future releases of SQLite.







>
>
>







1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
#define SQLITE_CONFIG_PCACHE       14  /* no-op */
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite4_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite4_pcache_methods2* */

#define SQLITE_CONFIG_SET_KVFACTORY 20 /* int(*)(KVStore**,const char*,u32) */
#define SQLITE_CONFIG_GET_KVFACTORY 21 /* int(**)(KVStore**,const char*,u32) */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite4_db_config()] interface.
**
** New configuration options may be added in future releases of SQLite.

Changes to src/sqliteInt.h.

18
19
20
21
22
23
24

25
26
27
28
29
30
31
...
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
....
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
....
1341
1342
1343
1344
1345
1346
1347







1348
1349
1350
1351
1352
1353
1354
....
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
....
2485
2486
2487
2488
2489
2490
2491


2492
2493
2494
2495
2496
2497
2498
....
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
....
2852
2853
2854
2855
2856
2857
2858

2859
2860
2861
2862
2863
2864
2865
....
2876
2877
2878
2879
2880
2881
2882


2883
2884
2885
2886
2887
2888
2889
....
3080
3081
3082
3083
3084
3085
3086






3087
3088
3089
3090
3091
3092
3093
....
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
/*#define SQLITE_OMIT_BTREECOUNT 1*/
#define SQLITE_OMIT_WAL 1
#define SQLITE_OMIT_VACUUM 1
#define SQLITE_OMIT_AUTOVACUUM 1
#define SQLITE_OMIT_SHARED_CACHE 1
/*#define SQLITE_OMIT_PAGER_PRAGMAS 1*/
#define SQLITE_OMIT_PROGRESS_CALLBACK 1

#define SQLITE_OMIT_MERGE_SORT 1

/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
................................................................................
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"
................................................................................
** refers VDBE cursor number that holds the table open, not to the root
** page number.  Transient tables are used to hold the results of a
** sub-query that appears instead of a real table name in the FROM clause 
** of a SELECT statement.
*/
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 */
#ifndef SQLITE_OMIT_CHECK
  Expr *pCheck;        /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
#  define IsVirtual(X)      (((X)->tabFlags & TF_Virtual)!=0)
#  define IsHiddenColumn(X) ((X)->isHidden)
#else
#  define IsVirtual(X)      0
#  define IsHiddenColumn(X) 0
#endif








/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
** key.  The "to" table is the table that is named in the REFERENCES clause.
................................................................................
** 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 isMallocInit;                 /* True after malloc is initialized */
  int isPCacheInit;                 /* True after malloc is initialized */
  sqlite4_mutex *pInitMutex;        /* Mutex used by sqlite4_initialize() */
  int nRefInitMutex;                /* Number of users of pInitMutex */
  void (*xLog)(void*,int,const char*); /* Function for logging */
  void *pLogArg;                       /* First argument to xLog() */
  int bLocaltimeFault;              /* True to fail localtime() calls */


};

/*
** Context pointer passed down through the tree-walk.
*/
struct Walker {
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
................................................................................
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);
................................................................................
int sqlite4ExprCanBeNull(const Expr*);
void sqlite4ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
int sqlite4ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite4IsRowid(const char*);
void sqlite4GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
void sqlite4GenerateRowIndexDelete(Parse*, Table*, int, int*);
int sqlite4GenerateIndexKey(Parse*, Index*, int, int, int, int);

void sqlite4GenerateConstraintChecks(Parse*,Table*,int,int,
                                     int*,int,int,int,int,int*);
void sqlite4CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
int sqlite4OpenTableAndIndices(Parse*, Table*, int, int);
void sqlite4BeginWriteOperation(Parse*, int, int);
void sqlite4MultiWrite(Parse*);
void sqlite4MayAbort(Parse*);
................................................................................
void sqlite4RegisterGlobalFunctions(void);
int sqlite4SafetyCheckOk(sqlite4*);
int sqlite4SafetyCheckSickOrOk(sqlite4*);
void sqlite4ChangeCookie(Parse*, int);

#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
void sqlite4MaterializeView(Parse*, Table*, Expr*, int);


#endif

#ifndef SQLITE_OMIT_TRIGGER
  void sqlite4BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
                           Expr*,int, int);
  void sqlite4FinishTrigger(Parse*, TriggerStep*, Token*);
  void sqlite4DropTrigger(Parse*, SrcList*, 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*);
#ifdef YYTRACKMAXSTACKDEPTH
................................................................................
** this case foreign keys are parsed, but no other functionality is 
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
  void sqlite4FkCheck(Parse*, Table*, int, int);
  void sqlite4FkDropTable(Parse*, SrcList *, Table*);
  void sqlite4FkActions(Parse*, Table*, ExprList*, int);
  int sqlite4FkRequired(Parse*, Table*, int*, int);
  u32 sqlite4FkOldmask(Parse*, Table*);
  FKey *sqlite4FkReferences(Table *);
#else
  #define sqlite4FkActions(a,b,c,d)
  #define sqlite4FkCheck(a,b,c,d)
  #define sqlite4FkDropTable(a,b,c)
  #define sqlite4FkOldmask(a,b)      0
  #define sqlite4FkRequired(a,b,c,d) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  void sqlite4FkDelete(sqlite4 *, Table*);
#else
  #define sqlite4FkDelete(a,b)
#endif








>







 







>







 







>







 







<



<




<







 







>
>
>
>
>
>
>







 







>







 







|













>
>
>
>
>







 







>

>







 







>
>







 







>
>
>
>
>
>







 







|







 







>







 







>
>







 







>
>
>
>
>
>







 







|







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
....
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301

1302
1303
1304
1305

1306
1307
1308
1309
1310
1311
1312
....
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
....
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
....
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
....
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
....
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
....
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
....
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
....
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
....
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
....
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
....
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
/*#define SQLITE_OMIT_BTREECOUNT 1*/
#define SQLITE_OMIT_WAL 1
#define SQLITE_OMIT_VACUUM 1
#define SQLITE_OMIT_AUTOVACUUM 1
#define SQLITE_OMIT_SHARED_CACHE 1
/*#define SQLITE_OMIT_PAGER_PRAGMAS 1*/
#define SQLITE_OMIT_PROGRESS_CALLBACK 1

#define SQLITE_OMIT_MERGE_SORT 1

/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
................................................................................
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"
................................................................................
** refers VDBE cursor number that holds the table open, not to the root
** page number.  Transient tables are used to hold the results of a
** sub-query that appears instead of a real table name in the FROM clause 
** of a SELECT statement.
*/
struct Table {
  char *zName;         /* Name of the table or view */

  int nCol;            /* Number of columns in this table */
  Column *aCol;        /* Information about each column */
  Index *pIndex;       /* List of SQL indexes on this table. */

  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 */

  FKey *pFKey;         /* Linked list of all foreign keys in this table */
  char *zColAff;       /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
  Expr *pCheck;        /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
#  define IsVirtual(X)      (((X)->tabFlags & TF_Virtual)!=0)
#  define IsHiddenColumn(X) ((X)->isHidden)
#else
#  define IsVirtual(X)      0
#  define IsHiddenColumn(X) 0
#endif

/* Test to see if a table is actually a view. */
#ifndef SQLITE_OMIT_VIEW
#  define IsView(X)         ((X)->pSelect!=0)
#else
#  define IsView(X)         0
#endif

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
** key.  The "to" table is the table that is named in the REFERENCES clause.
................................................................................
** 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 isMallocInit;                 /* True after malloc is initialized */
  int isPCacheInit;                 /* True after malloc is initialized */
  sqlite4_mutex *pInitMutex;        /* Mutex used by sqlite4_initialize() */
  int nRefInitMutex;                /* Number of users of pInitMutex */
  void (*xLog)(void*,int,const char*); /* Function for logging */
  void *pLogArg;                       /* First argument to xLog() */
  int bLocaltimeFault;              /* True to fail localtime() calls */
  int (*xKVFile)(KVStore **, const char *, unsigned int);
  int (*xKVTmp)(KVStore **, const char *, unsigned int);
};

/*
** Context pointer passed down through the tree-walk.
*/
struct Walker {
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
................................................................................
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);
................................................................................
int sqlite4ExprCanBeNull(const Expr*);
void sqlite4ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
int sqlite4ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite4IsRowid(const char*);
void sqlite4GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
void sqlite4GenerateRowIndexDelete(Parse*, Table*, int, int*);
int sqlite4GenerateIndexKey(Parse*, Index*, int, int, int, int);
void sqlite4EncodeIndexKey(Parse *, Index *, int, Index *, int, int);
void sqlite4GenerateConstraintChecks(Parse*,Table*,int,int,
                                     int*,int,int,int,int,int*);
void sqlite4CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
int sqlite4OpenTableAndIndices(Parse*, Table*, int, int);
void sqlite4BeginWriteOperation(Parse*, int, int);
void sqlite4MultiWrite(Parse*);
void sqlite4MayAbort(Parse*);
................................................................................
void sqlite4RegisterGlobalFunctions(void);
int sqlite4SafetyCheckOk(sqlite4*);
int sqlite4SafetyCheckSickOrOk(sqlite4*);
void sqlite4ChangeCookie(Parse*, int);

#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
void sqlite4MaterializeView(Parse*, Table*, Expr*, int);
#else
# define sqlite4MaterializeView(w,x,y,z)
#endif

#ifndef SQLITE_OMIT_TRIGGER
  void sqlite4BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
                           Expr*,int, int);
  void sqlite4FinishTrigger(Parse*, TriggerStep*, Token*);
  void sqlite4DropTrigger(Parse*, SrcList*, 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*);
#ifdef YYTRACKMAXSTACKDEPTH
................................................................................
** this case foreign keys are parsed, but no other functionality is 
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
  void sqlite4FkCheck(Parse*, Table*, int, int);
  void sqlite4FkDropTable(Parse*, SrcList *, Table*);
  void sqlite4FkActions(Parse*, Table*, ExprList*, int);
  int sqlite4FkRequired(Parse*, Table*, int*);
  u32 sqlite4FkOldmask(Parse*, Table*);
  FKey *sqlite4FkReferences(Table *);
#else
  #define sqlite4FkActions(a,b,c,d)
  #define sqlite4FkCheck(a,b,c,d)
  #define sqlite4FkDropTable(a,b,c)
  #define sqlite4FkOldmask(a,b)      0
  #define sqlite4FkRequired(a,b,c) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  void sqlite4FkDelete(sqlite4 *, Table*);
#else
  #define sqlite4FkDelete(a,b)
#endif

Changes to src/storage.c.

84
85
86
87
88
89
90
91








92
93
94
95
96
97
98
...
301
302
303
304
305
306
307








308
309
310
311
312
313
314
...
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
  const char *zUri,        /* URI for this database */
  KVStore **ppKVStore,     /* Write the new KVStore object here */
  unsigned flags           /* Option flags */
){
  KVStore *pNew = 0;
  int rc;

  rc = sqlite4KVStoreOpenMem(&pNew, flags);








  *ppKVStore = pNew;
  if( pNew ){
    sqlite4_randomness(sizeof(pNew->kvId), &pNew->kvId);
    sqlite4_snprintf(sizeof(pNew->zKVName), pNew->zKVName,
                     "%s", zName);
    pNew->fTrace = (db->flags & SQLITE_KvTrace)!=0;
    kvTrace(pNew, "open(%s,%d,0x%04x)", zUri, pNew->kvId, flags);
................................................................................
  return rc;
}

/*
** Key for the meta-data
*/
static const KVByteArray metadataKey[] = { 0x00, 0x00 };









/*
** Read nMeta unsigned 32-bit integers of metadata beginning at iStart.
*/
int sqlite4KVStoreGetMeta(KVStore *p, int iStart, int nMeta, unsigned int *a){
  KVCursor *pCur;
  int rc;
................................................................................
  KVStore *p,             /* Write to this database */
  int iStart,             /* Start writing here */
  int nMeta,              /* number of 32-bit integers to be written */
  unsigned int *a         /* The integers to write */
){
  KVCursor *pCur;
  int rc;
  int i, j;
  KVSize nData;
  const KVByteArray *aData;
  KVByteArray *aNew;
  KVSize nNew;


  rc = sqlite4KVStoreOpenCursor(p, &pCur);
  if( rc==SQLITE_OK ){






    rc = sqlite4KVCursorSeek(pCur, metadataKey, sizeof(metadataKey), 0);
    if( rc==SQLITE_OK ){
      rc = sqlite4KVCursorData(pCur, 0, -1, &aData, &nData);
    }else if( rc==SQLITE_NOTFOUND ){
      nData = 0;
      aData = 0;
      rc = SQLITE_OK;
    }


    if( rc==SQLITE_OK ){
      nNew = iStart+nMeta;
      if( nNew<nData ) nNew = nData;
      aNew = sqlite4DbMallocRaw(db, nNew*sizeof(a[0]) );
      if( aNew==0 ){
        rc = SQLITE_NOMEM;
      }else{

        memcpy(aNew, aData, nData);
        i = 0;
        j = iStart*4;
        while( i<nMeta && j+3<nData ){
          aNew[j] = (a[i]>>24)&0xff;
          aNew[j+1] = (a[i]>>16)&0xff;
          aNew[j+2] = (a[i]>>8)&0xff;
          aNew[j+3] = a[i] & 0xff;
          i++;
          j += 4;
        }
        rc = sqlite4KVStoreReplace(p, metadataKey, sizeof(metadataKey),
                                   aNew, nNew);
        sqlite4DbFree(db, aNew);
      }
    }

    sqlite4KVCursorClose(pCur);
  }
  return rc;
}

#if defined(SQLITE_DEBUG)
/*







|
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







<
<
<
<
<
>



>
>
>
>
>
>








>
>

|

|



>

<
|
|
<
<
<
<
<
<






>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
...
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
  const char *zUri,        /* URI for this database */
  KVStore **ppKVStore,     /* Write the new KVStore object here */
  unsigned flags           /* Option flags */
){
  KVStore *pNew = 0;
  int rc;

  if( zUri && zUri[0] 
   && sqlite4GlobalConfig.xKVFile 
   && memcmp(":memory:", zUri, 8)
  ){
    rc = sqlite4GlobalConfig.xKVFile(&pNew, zUri, flags);
  }else{
    rc = sqlite4GlobalConfig.xKVTmp(&pNew, zUri, flags);
  }

  *ppKVStore = pNew;
  if( pNew ){
    sqlite4_randomness(sizeof(pNew->kvId), &pNew->kvId);
    sqlite4_snprintf(sizeof(pNew->zKVName), pNew->zKVName,
                     "%s", zName);
    pNew->fTrace = (db->flags & SQLITE_KvTrace)!=0;
    kvTrace(pNew, "open(%s,%d,0x%04x)", zUri, pNew->kvId, flags);
................................................................................
  return rc;
}

/*
** Key for the meta-data
*/
static const KVByteArray metadataKey[] = { 0x00, 0x00 };

static void writeMetaArray(KVByteArray *aMeta, int iElem, u32 iVal){
  int i = sizeof(u32) * iElem;
  aMeta[i+0] = (iVal>>24)&0xff;
  aMeta[i+1] = (iVal>>16)&0xff;
  aMeta[i+2] = (iVal>>8) &0xff;
  aMeta[i+3] = (iVal>>0) &0xff;
}

/*
** Read nMeta unsigned 32-bit integers of metadata beginning at iStart.
*/
int sqlite4KVStoreGetMeta(KVStore *p, int iStart, int nMeta, unsigned int *a){
  KVCursor *pCur;
  int rc;
................................................................................
  KVStore *p,             /* Write to this database */
  int iStart,             /* Start writing here */
  int nMeta,              /* number of 32-bit integers to be written */
  unsigned int *a         /* The integers to write */
){
  KVCursor *pCur;
  int rc;







  rc = sqlite4KVStoreOpenCursor(p, &pCur);
  if( rc==SQLITE_OK ){
    const KVByteArray *aData;     /* Original database meta-array value */
    KVSize nData;                 /* Size of aData[] in bytes */
    KVByteArray *aNew;            /* New database meta-array value */
    KVSize nNew;                  /* Size of aNew[] in bytes */

    /* Read the current meta-array value from the database */
    rc = sqlite4KVCursorSeek(pCur, metadataKey, sizeof(metadataKey), 0);
    if( rc==SQLITE_OK ){
      rc = sqlite4KVCursorData(pCur, 0, -1, &aData, &nData);
    }else if( rc==SQLITE_NOTFOUND ){
      nData = 0;
      aData = 0;
      rc = SQLITE_OK;
    }

    /* Encode and write the new meta-array value to the database */
    if( rc==SQLITE_OK ){
      nNew = sizeof(a[0]) * (iStart+nMeta);
      if( nNew<nData ) nNew = nData;
      aNew = sqlite4DbMallocRaw(db, nNew);
      if( aNew==0 ){
        rc = SQLITE_NOMEM;
      }else{
        int i;
        memcpy(aNew, aData, nData);

        for(i=iStart; i<iStart+nMeta; i++){
          writeMetaArray(aNew, i, a[i]);






        }
        rc = sqlite4KVStoreReplace(p, metadataKey, sizeof(metadataKey),
                                   aNew, nNew);
        sqlite4DbFree(db, aNew);
      }
    }

    sqlite4KVCursorClose(pCur);
  }
  return rc;
}

#if defined(SQLITE_DEBUG)
/*

Changes to src/storage.h.

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
222
223
224
225
226
227
228






/*
** Valid flags for sqlite4KVStorageOpen()
*/
#define SQLITE_KVOPEN_TEMPORARY       0x0001  /* A temporary database */
#define SQLITE_KVOPEN_NO_TRANSACTIONS 0x0002  /* No transactions will be used */

int sqlite4KVStoreOpenMem(KVStore**, unsigned);
int sqlite4KVStoreOpen(
  sqlite4*,
  const char *zLabel, 
  const char *zUri,
  KVStore**,
  unsigned flags
);
................................................................................
int sqlite4KVStoreClose(KVStore *p);

int sqlite4KVStoreGetMeta(KVStore *p, int, int, unsigned int*);
int sqlite4KVStorePutMeta(sqlite4*, KVStore *p, int, int, unsigned int*);
#ifdef SQLITE_DEBUG
  void sqlite4KVStoreDump(KVStore *p);
#endif












|







 







>
>
>
>
>
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
222
223
224
225
226
227
228
229
230
231
232
233

/*
** Valid flags for sqlite4KVStorageOpen()
*/
#define SQLITE_KVOPEN_TEMPORARY       0x0001  /* A temporary database */
#define SQLITE_KVOPEN_NO_TRANSACTIONS 0x0002  /* No transactions will be used */

int sqlite4KVStoreOpenMem(KVStore**, const char *, unsigned);
int sqlite4KVStoreOpen(
  sqlite4*,
  const char *zLabel, 
  const char *zUri,
  KVStore**,
  unsigned flags
);
................................................................................
int sqlite4KVStoreClose(KVStore *p);

int sqlite4KVStoreGetMeta(KVStore *p, int, int, unsigned int*);
int sqlite4KVStorePutMeta(sqlite4*, KVStore *p, int, int, unsigned int*);
#ifdef SQLITE_DEBUG
  void sqlite4KVStoreDump(KVStore *p);
#endif

#ifdef SQLITE_ENABLE_LSM
int sqlite4KVStoreOpenLsm(KVStore**, const char *, unsigned);
#endif

Changes to src/tclsqlite.c.

3252
3253
3254
3255
3256
3257
3258

3259
3260
3261
3262
3263
3264
3265
....
3286
3287
3288
3289
3290
3291
3292

3293
3294
3295
3296
3297
3298
3299
    extern int Sqlitetestrtree_Init(Tcl_Interp*);
    extern int Sqlitequota_Init(Tcl_Interp*);
    extern int SqliteSuperlock_Init(Tcl_Interp*);
    extern int SqlitetestSyscall_Init(Tcl_Interp*);
    extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
    extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
    extern int Sqliteteststorage_Init(Tcl_Interp*);


#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
#endif

#ifdef SQLITE_ENABLE_ZIPVFS
    extern int Zipvfs_Init(Tcl_Interp*);
................................................................................
    SqlitetestOsinst_Init(interp);
    Sqlitetestintarray_Init(interp);
    Sqlitetestvfs_Init(interp);
    Sqlitetestrtree_Init(interp);
    Sqlitetestfuzzer_Init(interp);
    Sqlitetestwholenumber_Init(interp);
    Sqliteteststorage_Init(interp);


#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
    Sqlitetestfts3_Init(interp);
#endif

    Tcl_CreateObjCommand(
        interp, "load_testfixture_extensions", init_all_cmd, 0, 0







>







 







>







3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
....
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
    extern int Sqlitetestrtree_Init(Tcl_Interp*);
    extern int Sqlitequota_Init(Tcl_Interp*);
    extern int SqliteSuperlock_Init(Tcl_Interp*);
    extern int SqlitetestSyscall_Init(Tcl_Interp*);
    extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
    extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
    extern int Sqliteteststorage_Init(Tcl_Interp*);
    extern int Sqliteteststorage2_Init(Tcl_Interp*);

#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
#endif

#ifdef SQLITE_ENABLE_ZIPVFS
    extern int Zipvfs_Init(Tcl_Interp*);
................................................................................
    SqlitetestOsinst_Init(interp);
    Sqlitetestintarray_Init(interp);
    Sqlitetestvfs_Init(interp);
    Sqlitetestrtree_Init(interp);
    Sqlitetestfuzzer_Init(interp);
    Sqlitetestwholenumber_Init(interp);
    Sqliteteststorage_Init(interp);
    Sqliteteststorage2_Init(interp);

#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
    Sqlitetestfts3_Init(interp);
#endif

    Tcl_CreateObjCommand(
        interp, "load_testfixture_extensions", init_all_cmd, 0, 0

Changes to src/test_storage.c.

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
*/
static void storageSetTclErrorName(Tcl_Interp *interp, int rc){
  extern const char *sqlite4TestErrorName(int);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite4TestErrorName(rc), -1));
}

/*
** TCLCMD:    storage_open URI FLAGS
**
** Return a string that identifies the new storage object.
*/
static int test_storage_open(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  KVStore *pNew = 0;
  int rc;
  int flags;
  sqlite4 db;
  char zRes[50];
  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 2, objv, "URI FLAGS");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[2], &flags) ) return TCL_ERROR;


  memset(&db, 0, sizeof(db));
  rc = sqlite4KVStoreOpen(&db, "test", Tcl_GetString(objv[1]), &pNew, flags);
  if( rc ){
    sqlite4KVStoreClose(pNew);
    storageSetTclErrorName(interp, rc);
    return TCL_ERROR;
  }







|











|


|
|


|
>
>







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
*/
static void storageSetTclErrorName(Tcl_Interp *interp, int rc){
  extern const char *sqlite4TestErrorName(int);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite4TestErrorName(rc), -1));
}

/*
** TCLCMD:    storage_open URI ?FLAGS?
**
** Return a string that identifies the new storage object.
*/
static int test_storage_open(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  KVStore *pNew = 0;
  int rc;
  int flags = 0;
  sqlite4 db;
  char zRes[50];
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "URI ?FLAGS?");
    return TCL_ERROR;
  }
  if( objc==3 && Tcl_GetIntFromObj(interp, objv[2], &flags) ){
    return TCL_ERROR;
  }
  memset(&db, 0, sizeof(db));
  rc = sqlite4KVStoreOpen(&db, "test", Tcl_GetString(objv[1]), &pNew, flags);
  if( rc ){
    sqlite4KVStoreClose(pNew);
    storageSetTclErrorName(interp, rc);
    return TCL_ERROR;
  }

Added src/test_storage2.c.























































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
299
300
301
302
303
304
305
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
/*
** 2012 April 19
**
** 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.
**
*************************************************************************
**
*/

#include "sqliteInt.h"


static struct KVWrapGlobal {
  int (*xFactory)(KVStore **, const char *, unsigned int);
  int nStep;                      /* Total number of successful next/prev */
  int nSeek;                      /* Total number of calls to xSeek */
} kvwg = {0};

typedef struct KVWrap KVWrap;
typedef struct KVWrapCsr KVWrapCsr;

struct KVWrap {
  KVStore base;                   /* Base class, must be first */
  KVStore *pReal;                 /* "Real" KVStore object */
};

struct KVWrapCsr {
  KVCursor base;                  /* Base class. Must be first */
  KVCursor *pReal;                /* "Real" Cursor obecjt */
};

static int kvwrapBegin(KVStore *pKVStore, int iLevel){
  int rc;
  KVWrap *p = (KVWrap *)pKVStore;
  rc = p->pReal->pStoreVfunc->xBegin(p->pReal, iLevel);
  p->base.iTransLevel = p->pReal->iTransLevel;
  return rc;
}

static int kvwrapCommitPhaseOne(KVStore *pKVStore, int iLevel){
  int rc;
  KVWrap *p = (KVWrap *)pKVStore;
  rc = p->pReal->pStoreVfunc->xCommitPhaseOne(p->pReal, iLevel);
  p->base.iTransLevel = p->pReal->iTransLevel;
  return rc;
}

static int kvwrapCommitPhaseTwo(KVStore *pKVStore, int iLevel){
  int rc;
  KVWrap *p = (KVWrap *)pKVStore;
  rc = p->pReal->pStoreVfunc->xCommitPhaseTwo(p->pReal, iLevel);
  p->base.iTransLevel = p->pReal->iTransLevel;
  return rc;
}

static int kvwrapRollback(KVStore *pKVStore, int iLevel){
  int rc;
  KVWrap *p = (KVWrap *)pKVStore;
  rc = p->pReal->pStoreVfunc->xRollback(p->pReal, iLevel);
  p->base.iTransLevel = p->pReal->iTransLevel;
  return rc;
}

static int kvwrapRevert(KVStore *pKVStore, int iLevel){
  int rc;
  KVWrap *p = (KVWrap *)pKVStore;
  rc = p->pReal->pStoreVfunc->xRevert(p->pReal, iLevel);
  p->base.iTransLevel = p->pReal->iTransLevel;
  return rc;
}

static int kvwrapReplace(
  KVStore *pKVStore,
  const KVByteArray *aKey, KVSize nKey,
  const KVByteArray *aData, KVSize nData
){
  KVWrap *p = (KVWrap *)pKVStore;
  return p->pReal->pStoreVfunc->xReplace(p->pReal, aKey, nKey, aData, nData);
}

/*
** Create a new cursor object.
*/
static int kvwrapOpenCursor(KVStore *pKVStore, KVCursor **ppKVCursor){
  int rc = SQLITE_OK;
  KVWrap *p = (KVWrap *)pKVStore;
  KVWrapCsr *pCsr;

  pCsr = (KVWrapCsr *)sqlite4_malloc(sizeof(KVWrapCsr));
  if( pCsr==0 ){
    rc = SQLITE_NOMEM;
  }else{
    memset(pCsr, 0, sizeof(KVWrapCsr));
    rc = p->pReal->pStoreVfunc->xOpenCursor(p->pReal, &pCsr->pReal);
    if( rc!=SQLITE_OK ){
      sqlite4_free(pCsr);
      pCsr = 0;
    }else{
      pCsr->base.pStore = pKVStore;
      pCsr->base.pStoreVfunc = pKVStore->pStoreVfunc;
    }
  }

  *ppKVCursor = (KVCursor*)pCsr;
  return rc;
}

/*
** Reset a cursor
*/
static int kvwrapReset(KVCursor *pKVCursor){
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  return p->pReal->pStoreVfunc->xReset(pCsr->pReal);
}

/*
** Destroy a cursor object
*/
static int kvwrapCloseCursor(KVCursor *pKVCursor){
  int rc;
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  rc = p->pReal->pStoreVfunc->xCloseCursor(pCsr->pReal);
  sqlite4_free(pCsr);
  return rc;
}

/*
** Move a cursor to the next non-deleted node.
*/
static int kvwrapNextEntry(KVCursor *pKVCursor){
  int rc;
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  rc = p->pReal->pStoreVfunc->xNext(pCsr->pReal);
  if( rc==SQLITE_OK ) kvwg.nStep++;
  return rc;
}

/*
** Move a cursor to the previous non-deleted node.
*/
static int kvwrapPrevEntry(KVCursor *pKVCursor){
  int rc;
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  rc = p->pReal->pStoreVfunc->xPrev(pCsr->pReal);
  if( rc==SQLITE_OK ) kvwg.nStep++;
  return rc;
}

/*
** Seek a cursor.
*/
static int kvwrapSeek(
  KVCursor *pKVCursor, 
  const KVByteArray *aKey,
  KVSize nKey,
  int dir
){
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;

  /* If aKey[0]==0, this is a seek to retrieve meta-data. Don't count this. */
  if( aKey[0] ) kvwg.nSeek++;

  return p->pReal->pStoreVfunc->xSeek(pCsr->pReal, aKey, nKey, dir);
}

/*
** Delete the entry that the cursor is pointing to.
**
** Though the entry is "deleted", it still continues to exist as a
** phantom.  Subsequent xNext or xPrev calls will work, as will
** calls to xKey and xData, thought the result from xKey and xData
** are undefined.
*/
static int kvwrapDelete(KVCursor *pKVCursor){
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  return p->pReal->pStoreVfunc->xDelete(pCsr->pReal);
}

/*
** Return the key of the node the cursor is pointing to.
*/
static int kvwrapKey(
  KVCursor *pKVCursor,         /* The cursor whose key is desired */
  const KVByteArray **paKey,   /* Make this point to the key */
  KVSize *pN                   /* Make this point to the size of the key */
){
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  return p->pReal->pStoreVfunc->xKey(pCsr->pReal, paKey, pN);
}

/*
** Return the data of the node the cursor is pointing to.
*/
static int kvwrapData(
  KVCursor *pKVCursor,         /* The cursor from which to take the data */
  KVSize ofst,                 /* Offset into the data to begin reading */
  KVSize n,                    /* Number of bytes requested */
  const KVByteArray **paData,  /* Pointer to the data written here */
  KVSize *pNData               /* Number of bytes delivered */
){
  KVWrap *p = (KVWrap *)(pKVCursor->pStore);
  KVWrapCsr *pCsr = (KVWrapCsr *)pKVCursor;
  return p->pReal->pStoreVfunc->xData(pCsr->pReal, ofst, n, paData, pNData);
}

/*
** Destructor for the entire in-memory storage tree.
*/
static int kvwrapClose(KVStore *pKVStore){
  int rc;
  KVWrap *p = (KVWrap *)pKVStore;
  rc = p->pReal->pStoreVfunc->xClose(p->pReal);
  sqlite4_free(p);
  return rc;
}

static int newFileStorage(
  KVStore **ppKVStore,
  const char *zName,
  unsigned openFlags
){

  /* Virtual methods for an LSM data store */
  static const KVStoreMethods kvwrapMethods = {
    kvwrapReplace,
    kvwrapOpenCursor,
    kvwrapSeek,
    kvwrapNextEntry,
    kvwrapPrevEntry,
    kvwrapDelete,
    kvwrapKey,
    kvwrapData,
    kvwrapReset,
    kvwrapCloseCursor,
    kvwrapBegin,
    kvwrapCommitPhaseOne,
    kvwrapCommitPhaseTwo,
    kvwrapRollback,
    kvwrapRevert,
    kvwrapClose
  };

  KVWrap *pNew;
  int rc = SQLITE_OK;

  pNew = (KVWrap *)sqlite4_malloc(sizeof(KVWrap));
  if( pNew==0 ){
    rc = SQLITE_NOMEM;
  }else{
    memset(pNew, 0, sizeof(KVWrap));
    pNew->base.pStoreVfunc = &kvwrapMethods;
    rc = kvwg.xFactory(&pNew->pReal, zName, openFlags);
    if( rc!=SQLITE_OK ){
      sqlite4_free(pNew);
      pNew = 0;
    }
  }

  *ppKVStore = (KVStore*)pNew;
  return rc;
}

static int kvwrap_install_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 2, objv, "");
    return TCL_ERROR;
  }

  if( kvwg.xFactory==0 ){
    sqlite4_config(SQLITE_CONFIG_GET_KVFACTORY, &kvwg.xFactory);
    sqlite4_config(SQLITE_CONFIG_SET_KVFACTORY, newFileStorage);
  }
  return TCL_OK;
}

static int kvwrap_seek_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 2, objv, "");
    return TCL_ERROR;
  }

  Tcl_SetObjResult(interp, Tcl_NewIntObj(kvwg.nSeek));
  return TCL_OK;
}

static int kvwrap_step_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 2, objv, "");
    return TCL_ERROR;
  }

  Tcl_SetObjResult(interp, Tcl_NewIntObj(kvwg.nStep));
  return TCL_OK;
}

static int kvwrap_reset_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 2, objv, "");
    return TCL_ERROR;
  }

  kvwg.nStep = 0;
  kvwg.nSeek = 0;

  Tcl_ResetResult(interp);
  return TCL_OK;
}


/*
** TCLCMD:    kvwrap SUB-COMMAND
*/
static int kvwrap_command(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  struct Subcmd {
    const char *zCmd;
    int (*xCmd)(Tcl_Interp *, int, Tcl_Obj **);
  } aSub[] = {
    { "install", kvwrap_install_cmd },
    { "step",    kvwrap_step_cmd },
    { "seek",    kvwrap_seek_cmd },
    { "reset",   kvwrap_reset_cmd },
  };
  int iSub;
  int rc;

  rc = Tcl_GetIndexFromObjStruct(
      interp, objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
  );
  if( rc==TCL_OK ){
    rc = aSub[iSub].xCmd(interp, objc, (Tcl_Obj **)objv); 
  }

  return rc;
}

/*
** Register the TCL commands defined above with the TCL interpreter.
**
** This routine should be the only externally visible symbol in this
** source code file.
*/
int Sqliteteststorage2_Init(Tcl_Interp *interp){
  Tcl_CreateObjCommand(interp, "kvwrap", kvwrap_command, 0, 0);
  return TCL_OK;
}

Changes to src/update.c.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
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
...
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
...
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
400




401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
...
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
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
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
}

/*
** 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 */
................................................................................
  int nIdx;              /* Number of indices that need updating */
  int iCur;              /* VDBE Cursor number of pTab */
  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;
................................................................................
# define tmask 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  if( sqlite4ViewGetColumnNames(pParse, pTab) ){
    goto update_cleanup;
  }
  if( sqlite4IsReadOnly(pParse, pTab, tmask) ){
    goto update_cleanup;
  }
  aXRef = sqlite4DbMallocRaw(db, sizeof(int) * pTab->nCol );
  if( aXRef==0 ) goto update_cleanup;
  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;
  }
  regNew = pParse->nMem + 1;
  pParse->nMem += pTab->nCol;

  /* Start the view context. */
  if( isView ){
    sqlite4AuthContextPush(pParse, &sContext, pTab->zName);
  }

  /* If we are trying to update a view, realize that view into
................................................................................
  /* 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
    );




    for(i=0; i<pTab->nCol; i++){
      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++){
      if( aXRef[i]<0 && i!=pTab->iPKey ){
        sqlite4VdbeAddOp3(v, OP_Column, iCur, i, regNew+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
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
    sqlite4AutoincrementEnd(pParse);
  }

  /*
  ** Return the number of rows that were changed. If this routine is 
  ** generating code because of a call to sqlite4NestedParse(), do not
  ** invoke the callback function.
  */
  if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
    sqlite4VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
    sqlite4VdbeSetNumCols(v, 1);
    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
...
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
...
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
299
300
301
302
303
304
305
306
307
308
309
310

311

312
313
314
315
316
317
318
319
320
...
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
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
...
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
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
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
}

/*
** 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 */
................................................................................
  int nIdx;              /* Number of indices that need updating */
  int iCur;              /* VDBE Cursor number of pTab */
  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. */



  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 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 = 0;                 /* The primary key index of this table */
  int iPk = 0;                    /* 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 */
  int bImplicitPk = 0;            /* True if pTab has an implicit PK */
  int regOldTr = 0;               /* Content of OLD.* table including IPK */
  int regNewTr = 0;               /* Content of NEW.* table including IPK */

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

  /* Locate and analyze the table to be updated. This block sets:
  **
  **   pTab
  **   iDb
  **   pPk
  **   bImplicitPk
  */
  pTab = sqlite4SrcListLookup(pParse, pSrc);
  if( pTab==0 ) goto update_cleanup;
  iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema);
  if( IsView(pTab)==0 ){
    pPk = sqlite4FindPrimaryKey(pTab, &iPk);
    bImplicitPk = (pPk->aiColumn[0]<0);
  }

  /* 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;
................................................................................
# define tmask 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  if( sqlite4ViewGetColumnNames(pParse, pTab) ) goto update_cleanup;


  if( sqlite4IsReadOnly(pParse, pTab, tmask) ) goto update_cleanup;


  aXRef = sqlite4DbMallocRaw(db, sizeof(int) * pTab->nCol );
  if( aXRef==0 ) goto update_cleanup;
  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.  */
  iCur = pParse->nTab;
  pSrc->a[0].iCursor = iCur+iPk;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }
  if( IsView(pTab) ) 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. */
    if( !IsView(pTab) ){
      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
  /* TODO: This is currently broken */
  /* Virtual tables must be handled separately */
  if( IsVirtual(pTab) ){
    updateVirtualTable(pParse, pSrc, pTab, pChanges, 0, aXRef, pWhere, onError);

    pWhere = 0;
    pSrc = 0;
    goto update_cleanup;
  }
#endif

  hasFK = sqlite4FkRequired(pParse, pTab, aXRef);

  /* 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. Specifically:
  **
  **     regKeySet:     1 register
  **     regOldKey:     1 register
  **     regOldTr:      nCol+1 registers
  **     regNewTr:      nCol+1 registers
  **
  ** The regOldTr allocation is only required if there are either triggers 
  ** or foreign keys to be processed.
  **
  ** The regOldTr and regNewTr register arrays include space for the 
  ** implicit primary key value if the table in question does not have an
  ** explicit PRIMARY KEY.
  */
  regKeySet = ++pParse->nMem;
  regOldKey = ++pParse->nMem;
  if( pTrigger || hasFK ){
    regOldTr = pParse->nMem + 1;
    regOld = regOldTr+1;
    pParse->nMem += (pTab->nCol + 1);
  }

  regNewTr = pParse->nMem + 1;

  regNew = regNewTr+1;
  pParse->nMem += (pTab->nCol+1);

  /* Start the view context. */
  if( isView ){
    sqlite4AuthContextPush(pParse, &sContext, pTab->zName);
  }

  /* If we are trying to update a view, realize that view into
................................................................................
  /* 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+iPk, regOldKey);
  if( !okOnePass ){
    sqlite4VdbeAddOp2(v, OP_KeySetAdd, regKeySet, regOldKey);
  }
  sqlite4WhereEnd(pWInfo);

  /* 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; 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( bImplicitPk ){
      sqlite4VdbeAddOp2(v, OP_Rowid, iCur+iPk, regOldTr);
    }
    for(i=0; i<pTab->nCol; i++){
      if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
        sqlite4ExprCodeGetColumnOfTable(v, pTab, iCur+iPk, i, regOld+i);
      }else{
        sqlite4VdbeAddOp2(v, OP_Null, 0, regOld+i);
      }
    }



  }

  /* 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);
    }
  }
  if( bImplicitPk ){
    sqlite4VdbeAddOp2(v, OP_Rowid, iCur+iPk, regNew-1);
  }

  /* 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, regOldTr, 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.
    */
    sqlite4VdbeAddOp4Int(v, OP_NotFound, iCur+iPk, addr, regOldKey, 0);

    /* 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++){
      if( aXRef[i]<0 ){
        sqlite4VdbeAddOp3(v, OP_Column, iCur+iPk, i, regNew+i);
        sqlite4ColumnDefault(v, pTab, i, regNew+i);
      }
    }
  }

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

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

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

    /* Do FK constraint checks. */
    if( hasFK ){
      sqlite4FkCheck(pParse, pTab, regOld, 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 || bChngPk ){
      sqlite4VdbeAddOp2(v, OP_Delete, iCur, 0);
    }
    sqlite4VdbeJumpHere(v, j1);

    if( hasFK ){
      sqlite4FkCheck(pParse, pTab, 0, regNew);
    }
  
    /* 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);
    }
  }







  sqlite4CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
      TRIGGER_AFTER, pTab, regOldTr, 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 cursors */
  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    assert( aRegIdx );
    if( bOpenAll || aRegIdx[i] ){
      sqlite4VdbeAddOp2(v, OP_Close, iCur+i, 0);
    }
  }


  /* 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 ){
    sqlite4AutoincrementEnd(pParse);
  }












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

2140
2141
2142
2143
2144
2145
2146
....
2147
2148
2149
2150
2151
2152
2153

2154
2155
2156
2157

2158
2159
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
....
2238
2239
2240
2241
2242
2243
2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257



2258
2259
2260
2261
2262
2263
2264
....
2304
2305
2306
2307
2308
2309
2310







































2311
2312
2313
2314
2315
2316
2317
....
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354


2355
2356
2357
2358
2359
2360
2361
....
2601
2602
2603
2604
2605
2606
2607

2608
2609




2610
2611
2612
2613
2614
2615
2616
....
2670
2671
2672
2673
2674
2675
2676


















































2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
....
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
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
....
2894
2895
2896
2897
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
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
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
....
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
....
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
....
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
....
3435
3436
3437
3438
3439
3440
3441


3442
3443
3444
3445
3446
3447
3448
....
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593

3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
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
....
4097
4098
4099
4100
4101
4102
4103

4104
4105
4106
4107
4108
4109
4110
    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);

  break;
}

/* Opcode: Affinity P1 P2 * P4 *
**
** Apply affinities to a range of P2 registers starting with P1.
**
................................................................................
** P4 is a string that is P2 characters long. The nth character of the
** string indicates the column affinity that should be used for the nth
** memory cell in the range.
*/
case OP_Affinity: {
  const char *zAffinity;   /* The affinity to be applied */
  char cAff;               /* A single character of affinity */


  zAffinity = pOp->p4.z;
  assert( zAffinity!=0 );
  assert( zAffinity[pOp->p2]==0 );

  pIn1 = &aMem[pOp->p1];
  while( (cAff = *(zAffinity++))!=0 ){
    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);
................................................................................
      sqlite4VdbeMemExpandBlob(pMem);
    }
  }

  /* Compute the key (if this is a MakeKey opcode) */
  if( pC ){
    aRec = 0;
    rc = sqlite4VdbeEncodeKey(db, pData0, nField, pC->iRoot, pC->pKeyInfo,
                              &aRec, &nRec, 0);

    if( rc ){
      sqlite4DbFree(db, aRec);
    }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);
................................................................................
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then a ROLLBACK fails.  A COMMIT fails if
** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {







































  break;
}

/* Opcode: Transaction P1 P2 * * *
**
** Begin a transaction.
**
................................................................................
  if( pOp->p2==0 ){
    /* Read transaction needed.  Start if we are not already in one. */
    if( pKV->iTransLevel==0 ){
      rc = sqlite4KVStoreBegin(pKV, 1);
    }
  }else{
    /* A write transaction is needed */
    needStmt = pKV->iTransLevel>0 && (p->needSavepoint || db->activeVdbeCnt>1);
    if( pKV->iTransLevel<2 ){
      rc = sqlite4KVStoreBegin(pKV, 2);
    }else if( p->needSavepoint ){


      rc = sqlite4KVStoreBegin(pKV, pKV->iTransLevel+1);
      if( rc==SQLITE_OK ){
        p->stmtTransMask |= ((yDbMask)1)<<pOp->p1;
      }
    }
  }
  break;
................................................................................
case OP_OpenEphemeral: {
  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 *
................................................................................
*/
case OP_Close: {
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  sqlite4VdbeFreeCursor(p, p->apCsr[pOp->p1]);
  p->apCsr[pOp->p1] = 0;
  break;
}



















































/* Opcode: SeekGe P1 P2 P3 P4 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), 
** use the value in register P3 as the key.  If cursor P1 refers 
** to an SQL index, then P3 is the first in an array of P4 registers 
** that are used as an unpacked index key. 
**
** Reposition cursor P1 so that  it points to the smallest entry that 
** is greater than or equal to the key value. If there are no records 
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
*/
/* Opcode: SeekGt P1 P2 P3 P4 *
**
................................................................................
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLt:         /* jump, in3 */
case OP_SeekLe:         /* jump, in3 */
case OP_SeekGe:         /* jump, in3 */
case OP_SeekGt: {       /* jump, in3 */
  int oc;
  VdbeCursor *pC;
  int nField;
  KVByteArray *aProbe;
  KVSize nProbe;

  const KVByteArray *aKey;
  KVSize nKey;
  int c;
  int n;

  sqlite4_uint64 iRoot;


  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p2!=0 );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pseudoTableReg==0 );
  assert( OP_SeekLe == OP_SeekLt+1 );
  assert( OP_SeekGe == OP_SeekLt+2 );
  assert( OP_SeekGt == OP_SeekLt+3 );
  assert( pC->isOrdered );
  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, 
                           oc<=OP_SeekLe ? -1 : 1);
  sqlite4DbFree(db, aProbe);
  if( rc==SQLITE_OK ){
    if( oc==OP_SeekLt ){
      rc = sqlite4KVCursorPrev(pC->pKVCur);
    }else if( oc==OP_SeekGt ){
      rc = sqlite4KVCursorNext(pC->pKVCur);
    }
  }else if( rc==SQLITE_INEXACT ){
    rc = SQLITE_OK;
  }
  if( rc==SQLITE_OK ){
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE_OK ){
      iRoot = 0;
      n = sqlite4GetVarint64(aKey, nKey, &iRoot);
      if( iRoot!=pC->iRoot ) rc = SQLITE_DONE;
      c = aKey[n];
      if( c<0x05 || c>0xfa ) rc = SQLITE_DONE;
    }
  }
  if( rc==SQLITE_DONE ){
    rc = SQLITE_OK;
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
................................................................................
    nProbe = pIn3->n;
    pFree = 0;
  }
  if( rc==SQLITE_OK ){
    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;
  KVSize nProbe;
  KVSize nShort;
  KVSize nData;
  int isUnique;
  i64 R;                             /* Rowid stored in register P3 */

  pIn3 = &aMem[pOp->p3];
  aMx = &aMem[pOp->p4.i];
  /* Assert that the values of parameters P1 and P4 are in range. */
  assert( pOp->p4type==P4_INT32 );
  assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );

  /* Find the index cursor. */
  pCx = p->apCsr[pOp->p1];
  pCx->seekResult = 0;
  pCx->cacheStatus = CACHE_STALE;
  pKVCur = pCx->pKVCur;
  nField = pCx->pKeyInfo->nField;

  /* If any of the values are NULL, take the jump. */
  nField = pCx->pKeyInfo->nField;
  for(ii=0; ii<nField; ii++){
    if( aMx[ii].flags & MEM_Null ){
      pc = pOp->p2 - 1;
      pCrsr = 0;
      break;
    }
  }
  assert( (aMx[nField].flags & MEM_Null)==0 );

  isUnique = 1;
  if( pCrsr!=0 ){
    /* Extract the value of R from register P3. */
    sqlite4VdbeMemIntegerify(pIn3);
    R = pIn3->u.i;

    /* Generate the probe key */
    rc = sqlite4VdbeEncodeKey(db, pIn3, nField, pCx->iRoot,
                              pCx->pKeyInfo, &pProbe, &nProbe, &nShort);
    if( rc==SQLITE_OK ){
      rc = sqlite4KVCursorSeek(pKVCur, pProbe, nProbe, +1);
      if( rc==SQLITE_OK ){
        /* Full key already exists in the index.  Not unique. */
        isUnique = 0;
      }else if( rc==SQLITE_INEXACT ){
        int c = sqlite4KVCursorCompare(pKVCur, pProbe, nShort);
        if( c>0 ){
          rc = sqlite4KVCursorPrev(pKVCur);
          if( rc==SQLITE_OK ){
            c = sqlite4KVCursorCompare(pKVCur, pProbe, nShort);
          }
        }
        if( c ) isUnique = 0;
      }
      sqlite4DbFree(db, pProbe);
      if( isUnique ){
        pc = pOp->p2 - 1;
      }else{
        /* Collision.  Copy the conflicting rowid into register P3. */
        rc = sqlite4KVCursorData(pKVCur, 0, -1, &aData, &nData);
        if( rc==SQLITE_OK ){
          rc = sqlite4VdbeCreateDecoder(db, aData, nData, nField, &pCodec);
          if( rc==SQLITE_OK ){
            rc = sqlite4VdbeDecodeValue(pCodec, nField-1, 0, pIn3);
            sqlite4VdbeDestroyDecoder(pCodec);
          }
        }
      }
    }
  }
#endif
  break;
}

/* Opcode: Sequence P1 P2 * * *
**
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
................................................................................
  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];
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
#ifndef SQLITE_OMIT_MERGE_SORT
  assert( pC->isSorter );
  rc = sqlite4VdbeSorterRowkey(pC, pOut);
#else
  pOp->opcode = OP_RowKey;
  pc--;
#endif
  break;
}

/* Opcode: RowData P1 P2 * * *
**
................................................................................
  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 * * *
**
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  rc = sqlite4VdbeSeekEnd(pC, -1);
  if( rc==SQLITE_NOTFOUND ){  
    rc = SQLITE_OK;
    if( pOp->p2 ) pc = pOp->p2 - 1;


  }
  break;
}


/* Opcode: Sort P1 P2 * * *
**
................................................................................
    pC->nullRow = 1;
    rc = SQLITE_OK;
  }
  pC->rowidIsValid = 0;
  break;
}

/* Opcode: IdxInsert P1 P2 * * P5
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions.  This opcode writes that key
** into the index P1.  Data for the entry is nil.
**
** P3 is a flag that provides a hint to the b-tree 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_SorterInsert: {      /* in2 */

  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->isSorter==(pOp->opcode==OP_SorterInsert) );
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  assert( pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  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.
................................................................................
** calling OP_Program instruction.
*/
case OP_Param: {           /* out2-prerelease */
  VdbeFrame *pFrame;
  Mem *pIn;
  pFrame = p->pFrame;
  pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];   

  sqlite4VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
  break;
}

#endif /* #ifndef SQLITE_OMIT_TRIGGER */

#ifndef SQLITE_OMIT_FOREIGN_KEY







>
>
>
>
|



>







>







 







>



|
>
|
<
|

>
|
<
>

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











|
<

|
|
|
>
>

<
|
>
>
>
>

<
>







 







<
<
<
<
<







 







|
|
>









|
|
>
>
>







 







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







 







|


<
>
>







 







>
|
|
>
>
>
>







 







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








|







 







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



<






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







 







|



>
>













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




|







 







|







 







<







 







<







 







|







 







<







 







|







 







>
>







 







|
<
<
<
<
<
<
<
<
<
<


>

<












>
|
>
|



|
|

<
<
<
<
<
<

|




<

<
<
<

>
>
>
>

<
|
>
>
>



|

>



|

|
|
<


<







 







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







 







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







 







>







2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
....
2153
2154
2155
2156
2157
2158
2159
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
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
2254
2255
2256
2257
....
2281
2282
2283
2284
2285
2286
2287





2288
2289
2290
2291
2292
2293
2294
....
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
....
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
....
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460
2461
2462
2463
2464
....
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
....
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
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
....
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
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
2948
2949
2950
2951
2952
2953
....
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
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
3136
3137
3138



































3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
....
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
....
3193
3194
3195
3196
3197
3198
3199

3200
3201
3202
3203
3204
3205
3206
....
3278
3279
3280
3281
3282
3283
3284

3285
3286
3287
3288
3289
3290
3291
....
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
....
3455
3456
3457
3458
3459
3460
3461

3462
3463
3464
3465
3466
3467
3468
....
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
....
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
....
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
3741
3742
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
....
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
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
....
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
....
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
    aData = (const KVByteArray*)pReg->z;
    nData = pReg->n;
  }else{
    aData = 0;
    MemSetTypeFlag(pDest, MEM_Null);
  }
  if( rc==SQLITE_OK && aData ){
    /* TODO: Fix this somehow... */
    int nField = pC->nField;
    if( pC->pKeyInfo && pC->pKeyInfo->nData ) 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( rc<100 );
  break;
}

/* Opcode: Affinity P1 P2 * P4 *
**
** Apply affinities to a range of P2 registers starting with P1.
**
................................................................................
** P4 is a string that is P2 characters long. The nth character of the
** string indicates the column affinity that should be used for the nth
** memory cell in the range.
*/
case OP_Affinity: {
  const char *zAffinity;   /* The affinity to be applied */
  char cAff;               /* A single character of affinity */
  Mem *pEnd;

  zAffinity = pOp->p4.z;
  assert( zAffinity!=0 );
  assert( sqlite4Strlen30(zAffinity)>=pOp->p2 );

  pEnd = &aMem[pOp->p2+pOp->p1];

  for(pIn1=&aMem[pOp->p1]; pIn1<pEnd; pIn1++){
    assert( memIsValid(pIn1) );
    memAboutToChange(p, pIn1);
    applyAffinity(pIn1, *(zAffinity++), encoding);

    REGISTER_TRACE(pIn1-aMem, 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. Normally,
** N is equal to the number of columns indexed by P1, plus the number of 
** trailing primary key columns (if any). 
**
** Or, if P4 is a non-zero integer, then it contains the value for N.
**
** This instruction encodes the N values into a database key and writes
** the result to register P3.
**
** No affinity transformations are applied to the input values before 
** they are encoded. 
*/
case OP_MakeIdxKey: {
  VdbeCursor *pC;
  KeyInfo *pKeyInfo;
  Mem *pData0;                    /* First in array of input registers */
  u8 *aRec;                       /* The constructed database key */
  int nRec;                       /* Size of aRec[] in bytes */
  int nField;                     /* Number of fields in encoded record */
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  memAboutToChange(p, pOut);

  nField = pKeyInfo->nField;
  if( pOp->p4type==P4_INT32 && pOp->p4.i ){
    nField = pOp->p4.i;
    assert( nField<=pKeyInfo->nField );
  }
  rc = sqlite4VdbeEncodeKey(
    db, pData0, nField, pC->iRoot, pKeyInfo, &aRec, &nRec, 0
  );

  if( rc ){
    sqlite4DbFree(db, aRec);
  }else{
    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);
................................................................................
      sqlite4VdbeMemExpandBlob(pMem);
    }
  }

  /* Compute the key (if this is a MakeKey opcode) */
  if( pC ){
    aRec = 0;
    rc = sqlite4VdbeEncodeKey(db, 
        pData0, pC->pKeyInfo->nField, pC->iRoot, pC->pKeyInfo, &aRec, &nRec, 0
    );
    if( rc ){
      sqlite4DbFree(db, aRec);
    }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);
................................................................................
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then a ROLLBACK fails.  A COMMIT fails if
** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
  int bAutoCommit;                /* New value for auto-commit flag */
  int bRollback;                  /* True to do transaction rollback */

  bAutoCommit = pOp->p1;
  bRollback = pOp->p2;
  assert( bAutoCommit==1 || bRollback==0 );

  if( bAutoCommit==db->autoCommit ){
    /* This branch is taken if the user is trying to BEGIN a transaction
    ** when one is already open, or trying to commit or rollback a transaction
    ** when none is open. Return a suitable error message.  */
    const char *zErr;
    if( bAutoCommit==0 ){
      zErr = "cannot start a transaction within a transaction";
    }else if( bRollback ){
      zErr = "cannot rollback - no transaction is active";
    }else{
      zErr = "cannot commit - no transaction is active";
    }
    sqlite4SetString(&p->zErrMsg, db, zErr);
    rc = SQLITE_ERROR;
  }

  else if( bAutoCommit==0 ){
    db->autoCommit = 0;
  }else{
    if( bRollback ){
      sqlite4RollbackAll(db);
    }else if( rc = sqlite4VdbeCheckFk(p, 1) ){
      rc = SQLITE_ERROR;
      goto vdbe_return;
    }

    db->autoCommit = 1;
    sqlite4VdbeHalt(p);
    rc = (p->rc ? SQLITE_DONE : SQLITE_ERROR);
    goto vdbe_return;
  }

  break;
}

/* Opcode: Transaction P1 P2 * * *
**
** Begin a transaction.
**
................................................................................
  if( pOp->p2==0 ){
    /* Read transaction needed.  Start if we are not already in one. */
    if( pKV->iTransLevel==0 ){
      rc = sqlite4KVStoreBegin(pKV, 1);
    }
  }else{
    /* A write transaction is needed */
    needStmt = db->autoCommit==0 && (p->needSavepoint || db->activeVdbeCnt>1);
    if( pKV->iTransLevel<2 ){
      rc = sqlite4KVStoreBegin(pKV, 2);

    }
    if( needStmt ){
      rc = sqlite4KVStoreBegin(pKV, pKV->iTransLevel+1);
      if( rc==SQLITE_OK ){
        p->stmtTransMask |= ((yDbMask)1)<<pOp->p1;
      }
    }
  }
  break;
................................................................................
case OP_OpenEphemeral: {
  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", 0, &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 *
................................................................................
*/
case OP_Close: {
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  sqlite4VdbeFreeCursor(p, p->apCsr[pOp->p1]);
  p->apCsr[pOp->p1] = 0;
  break;
}

/* Opcode: SeekPk P1 * P3 * *
**
** P1 must be a cursor open on a PRIMARY KEY index. P3 is a cursor open
** on an auxiliary index on the same table. P3 must be pointing to a valid
** index entry.
**
** This opcode seeks cursor P1 so that it points to the PK index entry
** that corresponds to the same table row as the current entry that 
** cursor P3 points to. The entry must exist. If it does not, this opcode
** throws an SQLITE_CORRUPT exception.
*/
case OP_SeekPk: {
  VdbeCursor *pPk;                /* Cursor P1 */
  VdbeCursor *pIdx;               /* Cursor P3 */
  KVByteArray *aKey;              /* Key data from cursor pIdx */
  KVSize nKey;                    /* Size of aKey[] in bytes */
  int nShort;                     /* Size of aKey[] without PK fields */
  KVByteArray *aPkKey;
  KVSize nPkKey;
  int nVarint;

  pPk = p->apCsr[pOp->p1];
  pIdx = p->apCsr[pOp->p3];
  assert( pIdx->pKeyInfo->nPK>0 );
  assert( pPk->pKeyInfo->nPK==0 );

  rc = sqlite4KVCursorKey(pIdx->pKVCur, &aKey, &nKey);
  if( rc==SQLITE_OK ){
    nShort = sqlite4VdbeShortKey(aKey, nKey, 
        pIdx->pKeyInfo->nField - pIdx->pKeyInfo->nPK
    );

    nPkKey = sqlite4VarintLen(pPk->iRoot) + nKey - nShort;
    aPkKey = sqlite4DbMallocRaw(db, nPkKey);

    if( aPkKey ){
      putVarint32(aPkKey, pPk->iRoot);
      memcpy(&aPkKey[nPkKey - (nKey-nShort)], &aKey[nShort], nKey-nShort);
      rc = sqlite4KVCursorSeek(pPk->pKVCur, aPkKey, nPkKey, 0);
      if( rc==SQLITE_NOTFOUND ){
        rc = SQLITE_CORRUPT_BKPT;
      }
      pPk->nullRow = 0;
      sqlite4DbFree(db, aPkKey);
    }
  }

  break;
}

/* Opcode: SeekGe P1 P2 P3 P4 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), 
** use the value in register P3 as the key.  If cursor P1 refers 
** to an SQL index, then P3 is the first in an array of P4 registers 
** that are used as an unpacked index key. 
**
** Reposition cursor P1 so that it points to the smallest entry that 
** is greater than or equal to the key value. If there are no records 
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
*/
/* Opcode: SeekGt P1 P2 P3 P4 *
**
................................................................................
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLt:         /* jump, in3 */
case OP_SeekLe:         /* jump, in3 */
case OP_SeekGe:         /* jump, in3 */
case OP_SeekGt: {       /* jump, in3 */
  int op;                         /* Copy of pOp->opcode (the op-code) */
  VdbeCursor *pC;                 /* Cursor P1 */
  int nField;                     /* Number of values to encode into key */
  KVByteArray *aProbe;            /* Buffer containing encoded key */
  KVSize nProbe;                  /* Size of aProbe[] in bytes */
  int dir;                        /* KV search dir (+ve or -ve) */
  const KVByteArray *aKey;        /* Pointer to final cursor key */

  KVSize nKey;                    /* Size of aKey[] in bytes */


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

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p2!=0 );

  assert( pC!=0 );
  assert( pC->pseudoTableReg==0 );
  assert( OP_SeekLe == OP_SeekLt+1 );
  assert( OP_SeekGe == OP_SeekLt+2 );
  assert( OP_SeekGt == OP_SeekLt+3 );
  assert( pC->isOrdered );

  /* Encode a database key consisting of the contents of the P4 registers
  ** starting at register P3. Have the vdbecodec module allocate an extra
  ** free byte at the end of the database key (see below).  */
  op = pOp->opcode;
  nField = pOp->p4.i;
  pIn3 = &aMem[pOp->p3];
  rc = sqlite4VdbeEncodeKey(
      db, pIn3, nField, pC->iRoot, pC->pKeyInfo, &aProbe, &nProbe, 1
  );

  /*   Opcode    search-dir    increment-key
  **  --------------------------------------
  **   SeekLt    -1            no
  **   SeekLe    -1            yes
  **   SeekGe    +1            no
  **   SeekGt    +1            yes
  */
  dir = +1;
  if( op==OP_SeekLe || op==OP_SeekLt ) dir = -1;
  if( op==OP_SeekLe || op==OP_SeekGt ) aProbe[nProbe++] = 0xFF;
  if( rc==SQLITE_OK ){
    rc = sqlite4KVCursorSeek(pC->pKVCur, aProbe, nProbe, dir);
  }
  if( rc==SQLITE_OK || rc==SQLITE_INEXACT ){
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE_OK && memcmp(aKey, aProbe, sqlite4VarintLen(pC->iRoot)) ){
      rc = SQLITE_NOTFOUND;
    }
  }

  /* Free the key allocated above. If no error has occurred but the cursor 
  ** does not currently point to a valid entry, jump to instruction P2.  */
  sqlite4DbFree(db, aProbe);
  if( rc==SQLITE_NOTFOUND ){

    rc = SQLITE_OK;
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
................................................................................
    nProbe = pIn3->n;
    pFree = 0;
  }
  if( rc==SQLITE_OK ){
    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, nProbe)==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. If the key can be inserted into the index without violating
** a UNIQUE constraint, jump to instruction P2. Otherwise, fall through
** to the next instruction.
**
** If P4 is a non-zero integer and the jump is not taken, then it is
** a register that currently contains a blob. At the start of the blob
** is a varint that contains the index number for the PRIMARY KEY index
** of the table. The contents of P4 are overwritten with an index key
** composed of the varint from the start of the initial blob content
** and the PRIMARY KEY values from the index entry causing the UNIQUE
** constraint to fail.
*/
case OP_IsUnique: {        /* jump, in3 */
  VdbeCursor *pC;
  Mem *pProbe;
  Mem *pOut;
  int iOut;
  int nShort;
  int dir;
  u64 dummy;

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

  assert( pOp->p4type==P4_INT32 );

  pProbe = &aMem[pOp->p3];
  pC = p->apCsr[pOp->p1];
  pOut = (pOp->p4.i==0 ? 0 : &aMem[pOp->p4.i]);
  assert( pOut==0 || (pOut->flags & MEM_Blob) );

  nShort = sqlite4VdbeShortKey(pProbe->z, pProbe->n, 
      pC->pKeyInfo->nField - pC->pKeyInfo->nPK
  );
  assert( nShort<=pProbe->n );
  assert( (nShort==pProbe->n)==(pC->pKeyInfo->nPK==0) );

  dir = (pC->pKeyInfo->nPK==0 ? 0 : 1);
  rc = sqlite4KVCursorSeek(pC->pKVCur, pProbe->z, nShort, dir);

  if( rc==SQLITE_OK && pOut ){
    sqlite4VdbeMemCopy(pOut, pProbe);
  }else 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, nShort)
       || (nKey==pProbe->n && 0==memcmp(pProbe->z, aKey, nKey))
      ){
        pc = pOp->p2-1;
      }else if( pOut ){
        iOut = sqlite4GetVarint64(pOut->z, pOut->n, &dummy);
        rc = sqlite4VdbeMemGrow(pOut, iOut+(pProbe->n - nShort), 1);
        if( rc==SQLITE_OK ){
          memcpy(&pOut->z[iOut], &aKey[nShort], (pProbe->n - nShort));
          pOut->n = iOut + (pProbe->n - nShort);



































        }
      }
    }
  }

  break;
}

/* Opcode: Sequence P1 P2 * * *
**
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
................................................................................
  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];
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
#ifndef SQLITE_OMIT_MERGE_SORT
  assert( pC->isSorter );
  rc = sqlite4VdbeSorterRowkey(pC, pOut);
#else
  pOp->opcode = OP_RowData;
  pc--;
#endif
  break;
}

/* Opcode: RowData P1 P2 * * *
**
................................................................................
  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 * * *
**
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  rc = sqlite4VdbeSeekEnd(pC, -1);
  if( rc==SQLITE_NOTFOUND ){  
    rc = SQLITE_OK;
    if( pOp->p2 ) pc = pOp->p2 - 1;
  }else{
    pC->nullRow = 0;
  }
  break;
}


/* Opcode: Sort P1 P2 * * *
**
................................................................................
    pC->nullRow = 1;
    rc = SQLITE_OK;
  }
  pC->rowidIsValid = 0;
  break;
}

/* Opcode: SorterInsert P1 P2 P3










*/
case OP_SorterInsert: {      /* in2 */
#ifndef SQLITE_OMIT_MERGE_SORT
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->isSorter==(pOp->opcode==OP_SorterInsert) );
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  assert( pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  if( rc==SQLITE_OK ){
    rc = sqlite4VdbeSorterWrite(db, pC, pIn2);
  }
  break;
#endif

  /* If OMIT_MERGE_SORT is defined, fall through to IdxInsert. */
}

/* Opcode: IdxInsert P1 P2 P3 * P5
**
** Register P3 holds the key and register P2 holds the data for an
** index entry.  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) );

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;

  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 or equal to the key in register P3, 
** then jump to instruction P2. Otherwise, fall through to the next VM
** instruction. The comparison is done using memcmp(), except that if P3
** is a prefix of the P1 key they are considered equal.
*/
case OP_IdxLT:          /* jump */
case OP_IdxLE:          /* jump */
case OP_IdxGE:          /* jump */
case OP_IdxGT: {        /* jump */
  VdbeCursor *pC;                 /* Cursor P1 */
  KVByteArray *aKey;              /* Key from cursor P1 */
  KVSize nKey;                    /* Size of aKey[] in bytes */
  Mem *pCmp;                      /* Memory cell to compare index key with */
  int nCmp;                       /* Bytes of data to compare using memcmp() */
  int res;                        /* Result of memcmp() call */
  int bJump;                      /* True to take the jump */

  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);
    switch( pOp->opcode ){
      case OP_IdxLT: bJump = (res <  0); break;
      case OP_IdxLE: bJump = (res <= 0); break;
      case OP_IdxGE: bJump = (res >= 0); break;
      case OP_IdxGT: bJump = (res >  0); break;
    }

    if( bJump ) 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.
................................................................................
** calling OP_Program instruction.
*/
case OP_Param: {           /* out2-prerelease */
  VdbeFrame *pFrame;
  Mem *pIn;
  pFrame = p->pFrame;
  pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];   
  assert( memIsValid(pIn) );
  sqlite4VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
  break;
}

#endif /* #ifndef SQLITE_OMIT_TRIGGER */

#ifndef SQLITE_OMIT_FOREIGN_KEY

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
...
379
380
381
382
383
384
385
386
387
388
389

390
391
392
393
394
395
396
  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 */
................................................................................
  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 **pzOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int *pnShort                 /* Number of bytes omitting primary key */
);
int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
int sqlite4VdbeDecodeIntKey(const KVByteArray*, KVSize, sqlite4_int64*);

int sqlite4MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite4VdbeExec(Vdbe*);
int sqlite4VdbeList(Vdbe*);
int sqlite4VdbeHalt(Vdbe*);
int sqlite4VdbeChangeEncoding(Mem *, int);
int sqlite4VdbeMemTooBig(Mem*);
int sqlite4VdbeMemCopy(Mem*, const Mem*);







>







 







>
>







 







|



>







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
...
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
  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 */
................................................................................
  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 **pzOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int bIncr                    /* Make the key "incrementable" */
);
int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
int sqlite4VdbeDecodeIntKey(const KVByteArray*, KVSize, sqlite4_int64*);
int sqlite4VdbeShortKey(u8 *, int, int);
int sqlite4MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite4VdbeExec(Vdbe*);
int sqlite4VdbeList(Vdbe*);
int sqlite4VdbeHalt(Vdbe*);
int sqlite4VdbeChangeEncoding(Mem *, int);
int sqlite4VdbeMemTooBig(Mem*);
int sqlite4VdbeMemCopy(Mem*, const Mem*);

Changes to src/vdbeaux.c.

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
....
1801
1802
1803
1804
1805
1806
1807
1808







1809







1810

1811
1812
1813
1814
1815

1816
1817
1818

1819
1820
1821
1822
1823
1824
1825
1826
1827
1828

1829
1830
1831



1832
1833
1834

1835
1836
1837
1838
1839
1840
1841








1842
1843









1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855




1856
1857
1858
1859
1860
1861
1862
1863
1864
1865

1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
      ** 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;
................................................................................
    return SQLITE_OK;
  }
  checkActiveVdbeCnt(db);

  if( p->pc<0 ){
    /* No commit or rollback needed if the program never started */
  }else{
    /* Check for immediate foreign key violations. */







    if( p->rc==SQLITE_OK ){







      sqlite4VdbeCheckFk(p, 0);

    }
  
    /* If the auto-commit flag is set and this is the only active writer 
    ** VM, then we do either a commit or rollback of the current transaction. 
    */

    if( !sqlite4VtabInSync(db) 
     && db->autoCommit 
     && db->writeVdbeCnt==(p->readOnly==0) 

    ){
      rc = sqlite4VdbeCheckFk(p, 1);
      if( rc!=SQLITE_OK ){
        rc = SQLITE_CONSTRAINT;
      }else{ 
        /* The auto-commit flag is true, the vdbe program was successful 
        ** or hit an 'OR FAIL' constraint and there are no deferred foreign
        ** key constraints to hold up the transaction. This means a commit 
        ** is required. */
        rc = vdbeCommit(db, p);

      }
      if( rc==SQLITE_BUSY && p->readOnly ){
        /* will return the error */



      }else if( rc!=SQLITE_OK ){
        p->rc = rc;
        sqlite4RollbackAll(db);

      }else{
        db->nDeferredCons = 0;
        sqlite4CommitInternalChanges(db);
      }
    }else{
      /* Not in auto-commit mode.  If the statement failed, rollback
      ** the effects of just this one statement */








      if( p->rc!=SQLITE_OK && p->stmtTransMask!=0 ){
        int i;









        for(i=0; i<db->nDb; i++){
          if( p->stmtTransMask & ((yDbMask)1)<<i ){
            KVStore *pKV = db->aDb[i].pKV;
            rc = sqlite4KVStoreRollback(pKV, pKV->iTransLevel-1);
            if( rc ){
              sqlite4RollbackAll(db);
              break;
            }
          }
        }
      }
    }




  }

  /* We have successfully halted and closed the VM.  Record this fact. */
  if( p->pc>=0 ){
    db->activeVdbeCnt--;
    if( !p->readOnly ){
      db->writeVdbeCnt--;
    }
    assert( db->activeVdbeCnt>=db->writeVdbeCnt );
  }

  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);
  if( p->db->mallocFailed ){
    p->rc = SQLITE_NOMEM;
  }

  return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}


/*
** Each VDBE holds the result of the most recent sqlite4_step() call
** in p->rc.  This routine sets that result back to SQLITE_OK.







|







 







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

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

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










>





<







1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
....
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827



1828
1829

1830
1831
1832
1833








1834
1835


1836
1837
1838
1839
1840

1841
1842
1843
1844
1845



1846
1847
1848
1849
1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895

1896
1897
1898
1899
1900
1901
1902
      ** 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;
................................................................................
    return SQLITE_OK;
  }
  checkActiveVdbeCnt(db);

  if( p->pc<0 ){
    /* No commit or rollback needed if the program never started */
  }else{
    /* eAction:
    **
    **    0 - Do commit, either statement or transaction.
    **    1 - Do rollback, either statement or transaction.
    **    2 - Do transaction rollback.
    */
    int eAction = (p->rc!=SQLITE_OK);

    if( p->rc==SQLITE_CONSTRAINT ){
      if( p->errorAction==OE_Rollback ){
        eAction = 2;
      }else if( p->errorAction==OE_Fail ){
        eAction = 0;
      }
    }

    if( eAction==0 && sqlite4VdbeCheckFk(p, 0) ){
      eAction = 1;
    }




    if( eAction==2 || ( 
          sqlite4VtabInSync(db)==0 

       && db->writeVdbeCnt==(p->readOnly==0) 
       && db->autoCommit 
    )){
      if( eAction==0 && sqlite4VdbeCheckFk(p, 1) ){








        eAction = 1;
      }



      if( eAction==0 ){
        int rc = vdbeCommit(db, p);
        if( rc!=SQLITE_OK ){
          p->rc = rc;

          eAction = 1;
        }else{
          assert( db->nDeferredCons<=0 );
          sqlite4CommitInternalChanges(db);
        }



      }

      if( eAction ){
        sqlite4RollbackAll(db);
        db->autoCommit = 1;
      }

      db->nDeferredCons = 0;
    }else if( p->stmtTransMask ){

      /* Auto-commit mode is turned off and no "OR ROLLBACK" constraint was
      ** encountered. So either commit (if eAction==0) or rollback (if 
      ** eAction==1) any statement transactions opened by this VM.  */

      int i;                           /* Used to iterate thru attached dbs */
      int (*xFunc)(KVStore *,int);     /* Commit or rollback function */

      assert( eAction==0 || eAction==1 );
      xFunc = (eAction ? sqlite4KVStoreRollback : sqlite4KVStoreCommit);
      for(i=0; i<db->nDb; i++){
        if( p->stmtTransMask & ((yDbMask)1)<<i ){
          KVStore *pKV = db->aDb[i].pKV;
          rc = xFunc(pKV, pKV->iTransLevel-1);
          if( rc ){
            sqlite4RollbackAll(db);
            break;
          }
        }
      }
    }

    if( p->changeCntOn ){
      sqlite4VdbeSetChanges(db, (eAction ? 0 : p->nChange));
    }
    p->nChange = 0;
  }

  /* We have successfully halted and closed the VM.  Record this fact. */
  if( p->pc>=0 ){
    db->activeVdbeCnt--;
    if( !p->readOnly ){
      db->writeVdbeCnt--;
    }
    assert( db->activeVdbeCnt>=db->writeVdbeCnt );
  }

  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);
  if( p->db->mallocFailed ){
    p->rc = SQLITE_NOMEM;
  }

  return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}


/*
** Each VDBE holds the result of the most recent sqlite4_step() call
** in p->rc.  This routine sets that result back to SQLITE_OK.

Changes to src/vdbecodec.c.

104
105
106
107
108
109
110


111
112
113

114
115

116
117
118
119
120
121
122
123
...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
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
...
656
657
658
659
660
661
662



663
664
665
666
667
668
669
    }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];
      }
      sqlite4VdbeMemSetInt64(pOut, v);
    }else if( type<=21 ){
      sqlite4_uint64 x;
      int e;
      double r;
      n = sqlite4GetVarint64(p->a+ofst, p->n-ofst, &x);
................................................................................
      p->aOut[p->nOut++] = 0x22;  /* Large positive values */
      e = encodeLargeFloatKey(r, p);
      if( e<=10 ) p->aOut[i] = 0x17+e;
    }
  }else
  if( flags & MEM_Str ){
    if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE_NOMEM;
    p->aOut[p->nOut++] = 0x0e;   /* Text */
    if( pColl==0 || pColl->xMkKey==0 ){
      memcpy(p->aOut+p->nOut, pMem->z, pMem->n);
      p->nOut += pMem->n;
    }else{
      n = pColl->xMkKey(pColl->pUser, pMem->z, pMem->n, p->aOut+p->nOut,
                        p->nAlloc - p->nOut);
      if( n > p->nAlloc - p->nOut ){
................................................................................
    unsigned char s, t;
    assert( flags & MEM_Blob );
    n = pMem->n;
    a = (u8*)pMem->z;
    s = 1;
    t = 0;
    if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE_NOMEM;
    p->aOut[p->nOut++] = 0x0f;   /* Blob */
     for(i=0; i<n; i++){
      unsigned char x = a[i];
      p->aOut[p->nOut++] = 0x80 | t | (x>>s);
      if( s<7 ){
        t = x<<(7-s);
        s++;
      }else{
................................................................................
  if( sortOrder==SQLITE_SO_DESC ){
    for(i=iStart; i<p->nOut; i++) p->aOut[i] ^= 0xff;
  }
  return SQLITE_OK;
}

/*



















































** Generate a record key from one or more data values
**
** Space to hold the key is obtained from sqlite4DbMalloc() and should
** 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;
  u8 *so;
  int iShort;
  int nField;
  CollSeq **aColl;
  CollSeq *xColl;
  static const CollSeq defaultColl;




  x.db = db;
  x.aOut = 0;
  x.nOut = 0;
  x.nAlloc = 0;
  *paOut = 0;
  *pnOut = 0;

  if( enlargeEncoderAllocation(&x, (nIn+1)*10) ) return SQLITE_NOMEM;
  x.nOut = sqlite4PutVarint64(x.aOut, iTabno);
  if( pKeyInfo ){
    nField = pKeyInfo->nField;
    iShort = nField - pKeyInfo->nPK;
    aColl = pKeyInfo->aColl;
    so = pKeyInfo->aSortOrder;
  }else{
    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;
  }
  return rc;
................................................................................
    memcpy(aBuf, aKey, nKey);
    aKey = aBuf;
    for(i=1; i<nKey; i++) aBuf[i] ^= 0xff;
    e = 0x13-x;
  }else if( x>=0x17 && x<=0x21 ){
    isNeg = 0;
    e = x-0x17;



  }else{
    return 0;
  }
  m = 0;
  i = 1;
  do{
    m = m*100 + aKey[i]/2;







>
>



>

<
>
|







 







|







 







|







 







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









|


|






<




>
>
>






>


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


>
>







 







>
>
>







104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
...
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
...
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
    }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 ){
      int iByte;
      sqlite4_int64 v = ((char*)p->a)[ofst];

      for(iByte=1; iByte<size; iByte++){
        v = v*256 + p->a[ofst+iByte];
      }
      sqlite4VdbeMemSetInt64(pOut, v);
    }else if( type<=21 ){
      sqlite4_uint64 x;
      int e;
      double r;
      n = sqlite4GetVarint64(p->a+ofst, p->n-ofst, &x);
................................................................................
      p->aOut[p->nOut++] = 0x22;  /* Large positive values */
      e = encodeLargeFloatKey(r, p);
      if( e<=10 ) p->aOut[i] = 0x17+e;
    }
  }else
  if( flags & MEM_Str ){
    if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE_NOMEM;
    p->aOut[p->nOut++] = 0x24;   /* Text */
    if( pColl==0 || pColl->xMkKey==0 ){
      memcpy(p->aOut+p->nOut, pMem->z, pMem->n);
      p->nOut += pMem->n;
    }else{
      n = pColl->xMkKey(pColl->pUser, pMem->z, pMem->n, p->aOut+p->nOut,
                        p->nAlloc - p->nOut);
      if( n > p->nAlloc - p->nOut ){
................................................................................
    unsigned char s, t;
    assert( flags & MEM_Blob );
    n = pMem->n;
    a = (u8*)pMem->z;
    s = 1;
    t = 0;
    if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE_NOMEM;
    p->aOut[p->nOut++] = 0x25;   /* Blob */
     for(i=0; i<n; i++){
      unsigned char x = a[i];
      p->aOut[p->nOut++] = 0x80 | t | (x>>s);
      if( s<7 ){
        t = x<<(7-s);
        s++;
      }else{
................................................................................
  if( sortOrder==SQLITE_SO_DESC ){
    for(i=iStart; i<p->nOut; i++) p->aOut[i] ^= 0xff;
  }
  return SQLITE_OK;
}

/*
** Variables aKey/nKey contain an encoded index key. This function returns
** the length (in bytes) of the key with all but the first nField fields
** removed.
*/
int sqlite4VdbeShortKey(
  u8 *aKey,                       /* Buffer containing encoded key */
  int nKey,                       /* Size of buffer aKey[] in bytes */
  int nField                      /* Number of fields */
){
  u8 *p = aKey;
  u8 *pEnd = &aKey[nKey];
  u64 dummy;
  int i;

  p = aKey;
  p += sqlite4GetVarint64(p, pEnd-p, &dummy);

  for(i=0; i<nField; i++){
    u8 c = *(p++);
    switch( c ){

      case 0x05:                  /* NULL */
      case 0x06:                  /* NaN */
      case 0x07:                  /* -ve infinity */
      case 0x15:                  /* zero */
      case 0x23:                  /* +ve infinity */
        break;

      case 0x24:                  /* Text */
      case 0x25:                  /* Blob */
        while( *(p++) );
        break;

      case 0x22:                  /* Large positive number */
      case 0x16:                  /* Small positive number */
      case 0x14:                  /* Small negative number */
      case 0x08:                  /* Large negative number */
        p += sqlite4GetVarint64(p, pEnd-p, &dummy);
        while( (*p++) & 0x01 );
        break;

      default:                    /* Medium sized number */
        while( (*p++) & 0x01 );
        break;
    }
  }

  return (p - aKey);
}

/*
** Generate a database key from one or more data values.
**
** Space to hold the key is obtained from sqlite4DbMalloc() and should
** 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 bIncr                    /* See above */
){
  int i;
  int rc = SQLITE_OK;
  KeyEncoder x;
  u8 *so;
  int iShort;

  CollSeq **aColl;
  CollSeq *xColl;
  static const CollSeq defaultColl;

  assert( pKeyInfo );
  assert( nIn<=pKeyInfo->nField );

  x.db = db;
  x.aOut = 0;
  x.nOut = 0;
  x.nAlloc = 0;
  *paOut = 0;
  *pnOut = 0;

  if( enlargeEncoderAllocation(&x, (nIn+1)*10) ) return SQLITE_NOMEM;
  x.nOut = sqlite4PutVarint64(x.aOut, iTabno);


  iShort = pKeyInfo->nField - pKeyInfo->nPK;
  aColl = pKeyInfo->aColl;
  so = pKeyInfo->aSortOrder;







  for(i=0; i<nIn && rc==SQLITE_OK; i++){

    rc = encodeOneKeyValue(&x, aIn+i, so ? so[i] : SQLITE_SO_ASC, aColl[i]);
  }

  if( rc==SQLITE_OK && bIncr ){ rc = enlargeEncoderAllocation(&x, 1); }
  if( rc ){
    sqlite4DbFree(db, x.aOut);
  }else{
    *paOut = x.aOut;
    *pnOut = x.nOut;
  }
  return rc;
................................................................................
    memcpy(aBuf, aKey, nKey);
    aKey = aBuf;
    for(i=1; i<nKey; i++) aBuf[i] ^= 0xff;
    e = 0x13-x;
  }else if( x>=0x17 && x<=0x21 ){
    isNeg = 0;
    e = x-0x17;
  }else if( x==0x15 ){
    *pVal = 0;
    return 1;
  }else{
    return 0;
  }
  m = 0;
  i = 1;
  do{
    m = m*100 + aKey[i]/2;

Changes to src/vdbecursor.c.

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
  KVSize nKey;
  KVSize nProbe;
  int rc;
  KVByteArray aProbe[16];

  assert( iEnd==(+1) || iEnd==(-1) );  
  nProbe = sqlite4PutVarint64(aProbe, pC->iRoot);
  aProbe[nProbe++] = 16 - iEnd*12;

  rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe, iEnd);
  if( rc==SQLITE_OK ){
    return SQLITE_CORRUPT;
  }
  if( rc==SQLITE_INEXACT ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE_OK && (nKey<nProbe-1 || memcmp(aKey, aProbe, nProbe-1)!=0) ){
      rc = SQLITE_NOTFOUND;
    }
  }

  return rc;
}

/*
** Move a VDBE cursor to the next element in its table.
** Return SQLITE_NOTFOUND if the seek falls of the end of the table.
*/







|
>
|

|
<
|

|



>







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
  KVSize nKey;
  KVSize nProbe;
  int rc;
  KVByteArray aProbe[16];

  assert( iEnd==(+1) || iEnd==(-1) );  
  nProbe = sqlite4PutVarint64(aProbe, pC->iRoot);
  aProbe[nProbe] = 0xFF;

  rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe+(iEnd==-1), iEnd);
  if( rc==SQLITE_OK ){
    rc = SQLITE_CORRUPT_BKPT;

  }else if( rc==SQLITE_INEXACT ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE_OK && (nKey<nProbe || memcmp(aKey, aProbe, nProbe)!=0) ){
      rc = SQLITE_NOTFOUND;
    }
  }

  return rc;
}

/*
** Move a VDBE cursor to the next element in its table.
** Return SQLITE_NOTFOUND if the seek falls of the end of the table.
*/

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.

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
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
....
1575
1576
1577
1578
1579
1580
1581

























1582
1583
1584
1585
1586
1587
1588
....
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615



1616
1617
1618
1619
1620


1621


1622

1623
1624
1625
1626
1627



1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644




1645
1646
1647
1648
1649

1650













1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663





1664
1665



1666
1667
1668

1669
1670
1671
1672
1673
1674
1675


1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
1706
1707

1708
1709
1710

1711
1712
1713
1714
1715

1716

1717
1718




1719
1720
1721
1722
1723
1724



1725





1726











1727
1728
1729
1730
1731
1732
1733
....
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
....
2879
2880
2881
2882
2883
2884
2885
2886

2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
....
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
....
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
3040
....
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
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
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
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
....
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
....
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
....
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
....
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
....
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
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
3997
3998
3999
4000
4001
4002
4003
4004
....
4034
4035
4036
4037
4038
4039
4040
4041
4042


4043

4044
4045
4046
4047
4048
4049
4050
....
4053
4054
4055
4056
4057
4058
4059



4060
4061

4062
4063

4064
4065
4066
4067
4068
4069
4070
....
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097

4098
4099
4100
4101


4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
....
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
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236

4237
4238
4239
4240
4241
4242
4243
....
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
....
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
....
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
....
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
....
5180
5181
5182
5183
5184
5185
5186

5187

5188
5189
5190
5191
5192
5193
5194
....
5197
5198
5199
5200
5201
5202
5203

5204
5205
5206
5207
5208
5209
5210
....
5223
5224
5225
5226
5227
5228
5229

5230
5231
5232
5233
5234
5235
5236
5237
** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
** But if the table is the right table of a left join, WhereLevel.wsFlags
** is set to WO_IN|WO_EQ.  The WhereLevel.wsFlags field can then be used as
** the "op" parameter to findTerm when we are resolving equality constraints.
** ISNULL constraints will then not be used on the right table of a left
** join.  Tickets #2177 and #2189.
*/
#define WHERE_ROWID_EQ     0x00001000  /* rowid=EXPR or rowid IN (...) */
#define WHERE_ROWID_RANGE  0x00002000  /* rowid<EXPR and/or rowid>EXPR */
#define WHERE_COLUMN_EQ    0x00010000  /* x=EXPR or x IN (...) or x IS NULL */
#define WHERE_COLUMN_RANGE 0x00020000  /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN    0x00040000  /* x IN (...) */
#define WHERE_COLUMN_NULL  0x00080000  /* x IS NULL */
#define WHERE_INDEXED      0x000f0000  /* Anything that uses an index */
#define WHERE_NOT_FULLSCAN 0x100f3000  /* Does not do a full table scan */
#define WHERE_IN_ABLE      0x000f1000  /* Able to support an IN operator */
................................................................................
  WhereClause *pWC,     /* The WHERE clause to be searched */
  int iCur,             /* Cursor number of LHS */
  int iColumn,          /* Column number of LHS */
  Bitmask notReady,     /* RHS must not overlap with this mask */
  u32 op,               /* Mask of WO_xx values describing operator */
  Index *pIdx           /* Must be compatible with this index, if not NULL */
){

  WhereTerm *pTerm;
  int k;

  assert( iCur>=0 );
  op &= WO_ALL;
  for(; pWC; pWC=pWC->pOuter){
    for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
      if( pTerm->leftCursor==iCur
         && (pTerm->prereqRight & notReady)==0
         && pTerm->u.leftColumn==iColumn
         && (pTerm->eOperator & op)!=0
      ){
        if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){



          Expr *pX = pTerm->pExpr;
          CollSeq *pColl;
          char idxaff;
          int j;
          Parse *pParse = pWC->pParse;
  
          idxaff = pIdx->pTable->aCol[iColumn].affinity;
          if( !sqlite4IndexAffinityOk(pX, idxaff) ) continue;
  

          /* Figure out the collation sequence required from an index for
          ** it to be useful for optimising expression pX. Store this
          ** value in variable pColl.
          */
          assert(pX->pLeft);
          pColl = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
          assert(pColl || pParse->nErr);
  
          for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
            if( NEVER(j>=pIdx->nColumn) ) return 0;



          }
          if( pColl && sqlite4StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;




        }
        return pTerm;
      }
    }
  }
  return 0;
}
................................................................................

/* Forward reference */
static void exprAnalyze(SrcList*, WhereClause*, int);

/*
** Call exprAnalyze on all terms in a WHERE clause.  
**
**



*/
static void exprAnalyzeAll(
  SrcList *pTabList,       /* the FROM clause */
  WhereClause *pWC         /* the WHERE clause to be analyzed */
){
  int i;
  for(i=pWC->nTerm-1; i>=0; i--){
................................................................................
      return 1;
    }
  }

  return 0;
}


























/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
** left-most table in the FROM clause of that same SELECT statement and
................................................................................
  Index *pIdx,            /* The index we are testing */
  int base,               /* Cursor number for the table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int nEqCol,             /* Number of index columns with == constraints */
  int wsFlags,            /* Index usages flags */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  int i, j;                       /* Loop counters */
  int sortOrder = 0;              /* XOR of index and ORDER BY sort direction */
  int nTerm;                      /* Number of ORDER BY terms */
  struct ExprList_item *pTerm;    /* A term of the ORDER BY clause */
  sqlite4 *db = pParse->db;




  if( !pOrderBy ) return 0;
  if( wsFlags & WHERE_COLUMN_IN ) return 0;
  if( pIdx->bUnordered ) return 0;



  nTerm = pOrderBy->nExpr;


  assert( nTerm>0 );


  /* Argument pIdx must either point to a 'real' named index structure, 
  ** or an index structure allocated on the stack by bestKVIndex() to
  ** represent the rowid index that is part of every table.  */
  assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );




  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  **
  ** Note that indices have pIdx->nColumn regular columns plus
  ** one additional column containing the rowid.  The rowid column
  ** of the index is also allowed to match against the ORDER BY
  ** clause.
  */
  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){
    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
    CollSeq *pColl;    /* The collating sequence of pExpr */
    int termSortOrder; /* Sort order for this term */
    int iColumn;       /* The i-th column of the index.  -1 for rowid */
    int iSortOrder;    /* 1 for DESC, 0 for ASC on the i-th index term */
    const char *zColl; /* Name of the collating sequence for i-th index term */





    pExpr = pTerm->pExpr;
    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
      /* Can not use an index sort on anything that is not a column in the
      ** left-most table of the FROM clause */
      break;

    }













    pColl = sqlite4ExprCollSeq(pParse, pExpr);
    if( !pColl ){
      pColl = db->pDfltColl;
    }
    if( pIdx->zName && i<pIdx->nColumn ){
      iColumn = pIdx->aiColumn[i];
      if( iColumn==pIdx->pTable->iPKey ){
        iColumn = -1;
      }
      iSortOrder = pIdx->aSortOrder[i];
      zColl = pIdx->azColl[i];
    }else{
      iColumn = -1;





      iSortOrder = 0;
      zColl = pColl->zName;



    }
    if( pExpr->iColumn!=iColumn || sqlite4StrICmp(pColl->zName, zColl) ){
      /* Term j of the ORDER BY clause does not match column i of the index */

      if( i<nEqCol ){
        /* If an index column that is constrained by == fails to match an
        ** ORDER BY term, that is OK.  Just ignore that column of the index
        */
        continue;
      }else if( i==pIdx->nColumn ){
        /* Index column i is the rowid.  All other terms match. */


        break;
      }else{
        /* If an index column fails to match and is not constrained by ==
        ** then the index cannot satisfy the ORDER BY constraint.
        */
        return 0;
      }
    }
    assert( pIdx->aSortOrder!=0 || iColumn==-1 );
    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
    assert( iSortOrder==0 || iSortOrder==1 );
    termSortOrder = iSortOrder ^ pTerm->sortOrder;
    if( i>nEqCol ){
      if( termSortOrder!=sortOrder ){
        /* Indices can only be used if all ORDER BY terms past the
        ** equality constraints are all either DESC or ASC. */
        return 0;
      }
    }else{
      sortOrder = termSortOrder;
    }
    j++;
    pTerm++;

    if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
      /* If the indexed column is the primary key and everything matches
      ** so far and none of the ORDER BY terms to the right reference other
      ** tables in the join, then we are assured that the index can be used 
      ** to sort because the primary key is unique and so none of the other
      ** columns will make any difference
      */
      j = nTerm;
    }

  }

  *pbRev = sortOrder!=0;

  if( j>=nTerm ){
    /* All terms of the ORDER BY clause are covered by this index so
    ** this index can be used for sorting. */
    return 1;
  }

  if( pIdx->onError!=OE_None && i==pIdx->nColumn

      && (wsFlags & WHERE_COLUMN_NULL)==0
      && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){




    /* All terms of this index match some prefix of the ORDER BY clause
    ** and the index is UNIQUE and no terms on the tail of the ORDER BY
    ** clause reference other tables in a join.  If this is all true then
    ** the order by clause is superfluous.  Not that if the matching
    ** condition is IS NULL then the result is not necessarily unique
    ** even on a UNIQUE index, so disallow those cases. */



    return 1;





  }











  return 0;
}

/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact.  This is only used for estimating
** the total cost of performing operations with O(logN) or O(NlogN)
................................................................................
    *pnRow = nRowEst;
    WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
  }
  return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */


/*
** Find the best query plan for accessing a particular table.  Write the
** best query plan and its cost into the WhereCost object supplied as the
** last parameter.
**
** The lowest cost plan wins.  The cost is an estimate of the amount of
** CPU and disk I/O needed to process the requested result.
................................................................................
  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
  ** use an index to satisfy IS NULL constraints on that table.  This is
................................................................................
  */
  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;
................................................................................
    int nEq;                      /* Number of == or IN terms matching index */
    int bInEst = 0;               /* True if "x IN (SELECT...)" seen */
    int nInMul = 1;               /* Number of distinct equalities to lookup */
    double rangeDiv = (double)1;  /* Estimated reduction in search space */
    int nBound = 0;               /* Number of range constraints seen */
    int bSort = !!pOrderBy;       /* True if external sort required */
    int bDist = !!pDistinct;      /* True if index cannot help with DISTINCT */
    int bLookup = 0;              /* True if not a covering index */
    WhereTerm *pTerm;             /* A single term of the WHERE clause */
#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) ){
          /* "x IN (SELECT ...)":  Assume the SELECT returns 25 rows */
          nInMul *= 25;
................................................................................
    ** at most a single row. In this case set the WHERE_UNIQUE flag to 
    ** indicate this to the caller.
    **
    ** Otherwise, if the search may find more than one row, test to see if
    ** there is a range constraint on indexed column (nEq+1) that can be 
    ** optimized using the index. 
    */
    if( nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
      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 );
        }
        if( pBtm ){
          nBound++;
          wsFlags |= WHERE_BTM_LIMIT;
          used |= pBtm->prereqRight;
          testcase( pBtm->pWC!=pWC );
        }
        wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
      }
    }

    /* If there is an ORDER BY clause and the index being considered will
    ** naturally scan rows in the required order, set the appropriate flags
    ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
    ** will scan rows in a different order, set the bSort variable.  */
    if( isSortingIndex(
          pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev)
    ){
      bSort = 0;
      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
      wsFlags |= (rev ? WHERE_REVERSE : 0);
    }

    /* If there is a DISTINCT qualifier and this index will scan rows in
    ** 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
  ** is set, then reverse the order that the index will be scanned
  ** in. This is used for application testing, to help find cases
  ** where application behaviour depends on the (undefined) order that
  ** SQLite outputs rows in in the absence of an ORDER BY clause.  */
  if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
    pCost->plan.wsFlags |= WHERE_REVERSE;
  }

  assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );
  assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 );
  assert( pSrc->pIndex==0 
       || pCost->plan.u.pIdx==0 
       || pCost->plan.u.pIdx==pSrc->pIndex 
  );

  WHERETRACE(("best index is: %s\n", 
    ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : 
................................................................................
          ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
          ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
          ((flags & WHERE_TEMP_INDEX)?"":" "),
          ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName),
          zWhere
      );
      sqlite4DbFree(db, zWhere);
    }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
      zMsg = sqlite4MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);

      if( flags&WHERE_ROWID_EQ ){
        zMsg = sqlite4MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
      }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
        zMsg = sqlite4MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
      }else if( flags&WHERE_BTM_LIMIT ){
        zMsg = sqlite4MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
      }else if( flags&WHERE_TOP_LIMIT ){
        zMsg = sqlite4MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
      sqlite4_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
      zMsg = sqlite4MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
                  pVtabIdx->idxNum, pVtabIdx->idxStr);
    }
................................................................................
    sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE_OMIT_EXPLAIN */


/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(
  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
  int iLevel,          /* Which level of pWInfo->a[] should be coded */
................................................................................
  u16 wctrlFlags,      /* One of the WHERE_* flags defined in sqliteInt.h */
  Bitmask notReady,    /* Which tables are currently available */
  Expr *pWhere         /* Complete WHERE clause */
){
  int j, k;            /* Loop counters */
  int iCur;            /* The VDBE cursor for the table */
  int addrNxt;         /* Where to jump to continue with the next IN case */
  int omitTable;       /* True if we use the index only */
  int bRev;            /* True if we need to scan in reverse order */
  WhereLevel *pLevel;  /* The where level to be coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  Parse *pParse;                  /* Parsing context */
  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
................................................................................
  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = pWInfo->pWC;
  pLevel = &pWInfo->a[iLevel];
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
  omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
           && (wctrlFlags & WHERE_FORCE_TABLE)==0;

  /* Create labels for the "break" and "continue" instructions
  ** for the current loop.  Jump to addrBrk to break out of a loop.
  ** Jump to cont to go immediately to the next iteration of the
  ** loop.
  **
  ** When there is an IN operator, we also have a "addrNxt" label that
................................................................................
    pLevel->p1 = iCur;
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2);
    sqlite4ExprCachePop(pParse, 1);
  }else
#endif /* SQLITE_OMIT_VIRTUALTABLE */

  if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){
    /* Case 1:  We can directly reference a single row using an
    **          equality comparison against the ROWID field.  Or
    **          we reference multiple rows using a "rowid IN (...)"
    **          construct.
    */
    iReleaseReg = sqlite4GetTempReg(pParse);
    pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
    assert( pTerm!=0 );
    assert( pTerm->pExpr!=0 );
    assert( pTerm->leftCursor==iCur );
    assert( omitTable==0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite4VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
    sqlite4VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
    sqlite4ExprCacheStore(pParse, iCur, -1, iRowidReg);
    VdbeComment((v, "pk"));
    pLevel->op = OP_Noop;
  }else if( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ){
    /* Case 2:  We have an inequality comparison against the ROWID field.
    */
    int testOp = OP_Noop;
    int start;
    int memEndValue = 0;
    WhereTerm *pStart, *pEnd;

    assert( omitTable==0 );
    pStart = findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0);
    pEnd = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0);
    if( bRev ){
      pTerm = pStart;
      pStart = pEnd;
      pEnd = pTerm;
    }
    if( pStart ){
      Expr *pX;             /* The expression that defines the start bound */
      int r1, rTemp;        /* Registers for holding the start boundary */

      /* The following constant maps TK_xx codes into corresponding 
      ** seek opcodes.  It depends on a particular ordering of TK_xx
      */
      const u8 aMoveOp[] = {
           /* TK_GT */  OP_SeekGt,
           /* TK_LE */  OP_SeekLe,
           /* TK_LT */  OP_SeekLt,
           /* TK_GE */  OP_SeekGe
      };
      assert( TK_LE==TK_GT+1 );      /* Make sure the ordering.. */
      assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
      assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */

      testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      pX = pStart->pExpr;
      assert( pX!=0 );
      assert( pStart->leftCursor==iCur );
      r1 = sqlite4ExprCodeTemp(pParse, pX->pRight, &rTemp);
      sqlite4VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
      VdbeComment((v, "pk"));
      sqlite4ExprCacheAffinityChange(pParse, r1, 1);
      sqlite4ReleaseTempReg(pParse, rTemp);
      disableTerm(pLevel, pStart);
    }else{
      sqlite4VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
    }
    if( pEnd ){
      Expr *pX;
      pX = pEnd->pExpr;
      assert( pX!=0 );
      assert( pEnd->leftCursor==iCur );
      testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      memEndValue = ++pParse->nMem;
      sqlite4ExprCode(pParse, pX->pRight, memEndValue);
      if( pX->op==TK_LT || pX->op==TK_GT ){
        testOp = bRev ? OP_Le : OP_Ge;
      }else{
        testOp = bRev ? OP_Lt : OP_Gt;
      }
      disableTerm(pLevel, pEnd);
    }
    start = sqlite4VdbeCurrentAddr(v);
    pLevel->op = bRev ? OP_Prev : OP_Next;
    pLevel->p1 = iCur;
    pLevel->p2 = start;
    if( pStart==0 && pEnd==0 ){
      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
    }else{
      assert( pLevel->p5==0 );
    }
    if( testOp!=OP_Noop ){
      iRowidReg = iReleaseReg = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
      sqlite4ExprCacheStore(pParse, iCur, -1, iRowidReg);
      sqlite4VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
      sqlite4VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
    }
  }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
    /* Case 3: A scan using an index.
    **
    **         The WHERE clause may contain zero or more equality 
    **         terms ("==" or "IN" operators) that refer to the N
    **         left-most columns of the index. It may also contain
    **         inequality constraints (>, <, >= or <=) on the indexed
    **         column that immediately follows the N equalities. Only 
................................................................................
      OP_SeekGt,           /* 4: (start_constraints  && !startEq && !bRev) */
      OP_SeekLt,           /* 5: (start_constraints  && !startEq &&  bRev) */
      OP_SeekGe,           /* 6: (start_constraints  &&  startEq && !bRev) */
      OP_SeekLe            /* 7: (start_constraints  &&  startEq &&  bRev) */
    };
    static const u8 aEndOp[] = {
      OP_Noop,             /* 0: (!end_constraints) */
      OP_IdxGE,            /* 1: (end_constraints && !bRev) */
      OP_IdxLT             /* 2: (end_constraints && bRev) */


    };

    int nEq = pLevel->plan.nEq;  /* Number of == or IN terms */
    int isMinQuery = 0;          /* If this is an optimized SELECT min(x).. */
    int regBase;                 /* Base register holding constraint values */
    int r1;                      /* Temp register */
    WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
    WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
    int startEq;                 /* True if range start uses ==, >= or <= */
................................................................................
    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) ..." 
    ** query, then the caller will only allow the loop to run for
    ** a single iteration. This means that the first row returned
    ** should not have a NULL value stored in 'x'. If column 'x' is
    ** the first one after the nEq equality constraints in the index,
................................................................................
      /* assert( pOrderBy->nExpr==1 ); */
      /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
      isMinQuery = 1;
      nExtraReg = 1;
    }

    /* Find any inequality constraint terms for the start and end 
    ** of the range. 
    */
    if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
      pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
      nExtraReg = 1;
    }
    if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
      pRangeStart = findTerm(pWC, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
      nExtraReg = 1;
    }

    /* Generate code to evaluate all constraint terms using == or IN
    ** and store the values of those terms in an array of registers
    ** starting at regBase.

    */
    regBase = codeAllEqualityTerms(
        pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff
    );


    zEndAff = sqlite4DbStrDup(pParse->db, zStartAff);
    addrNxt = pLevel->addrNxt;

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
    */
    if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
     || (bRev && pIdx->nColumn==nEq)
    ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
    }

    testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
................................................................................
    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.
    */
    r1 = sqlite4GetTempReg(pParse);
    testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
    testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
    if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
      sqlite4VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
      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 
    ** WHERE clause terms made redundant by the index range scan.
    */
    if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
      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:
................................................................................
  {
    /* Case 5:  There is no usable index.  We must do a complete
    **          scan of the entire table.
    */
    static const u8 aStep[] = { OP_Next, OP_Prev };
    static const u8 aStart[] = { OP_Rewind, OP_Last };
    assert( bRev==0 || bRev==1 );
    assert( omitTable==0 );
    pLevel->op = aStep[bRev];
    pLevel->p1 = iCur;
    pLevel->p2 = 1 + sqlite4VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
    pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
  }
  notReady &= ~getMask(pWC->pMaskSet, iCur);

................................................................................
      Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor);
      assert( (m-1)==toTheLeft );
      toTheLeft |= m;
    }
  }
#endif

  /* Analyze all of the subexpressions.  Note that exprAnalyze() might
  ** add new virtual terms onto the end of the WHERE clause.  We do not
  ** want to analyze these virtual terms, so start analyzing at the end
  ** and work forward so that the added virtual terms are never processed.
  */
  exprAnalyzeAll(pTabList, pWC);
  if( db->mallocFailed ){
    goto whereBeginError;
  }

  /* Check if the DISTINCT qualifier, if there is one, is redundant. 
  ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
................................................................................
      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;

................................................................................
        nQPlan += 2;
      }else{
        memcpy(&sqlite4_query_plan[nQPlan], z, n);
        nQPlan += n;
      }
      sqlite4_query_plan[nQPlan++] = ' ';
    }
    testcase( pLevel->plan.wsFlags & WHERE_ROWID_EQ );
    testcase( pLevel->plan.wsFlags & WHERE_ROWID_RANGE );
    if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
      memcpy(&sqlite4_query_plan[nQPlan], "* ", 2);
      nQPlan += 2;
    }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
      n = sqlite4Strlen30(pLevel->plan.u.pIdx->zName);
      if( n+nQPlan < sizeof(sqlite4_query_plan)-2 ){
        memcpy(&sqlite4_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
        nQPlan += n;
        sqlite4_query_plan[nQPlan++] = ' ';
      }
    }else{
................................................................................
     && (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
................................................................................
    ** 
    ** Calls to the code generator in between sqlite4WhereBegin and
    ** sqlite4WhereEnd will have created code that references the table
    ** directly.  This loop scans all that code looking for opcodes
    ** that reference the table and converts them into opcodes that
    ** reference the index.
    */

    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){
      int k, j, last;
      VdbeOp *pOp;
      Index *pIdx = pLevel->plan.u.pIdx;

      assert( pIdx!=0 );
      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
................................................................................
               || j<pIdx->nColumn );
        }else if( pOp->opcode==OP_Rowid ){
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowid;
        }
      }
    }

  }

  /* Final cleanup
  */
  pParse->nQueryLoop = pWInfo->savedNQueryLoop;
  whereInfoFree(db, pWInfo);
  return;
}







<
<







 







>


>










>
>
>

<
<



|
|
|
>
|
<
|
|


|
<
|
|
>
>
>

<
>
>
>
>







 







|
>
>
>







 







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







 







|


|
|
>
>
>





>
>

>
>

>

<
<
<
<
>
>
>

<
<
<
<
<
<
<
<
<




<


>
>
>
>

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

<
|
<
|
<
<
<
<
<
|

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

<
<
<
<
<

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









>



>
|
|
|


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







 







<







 







|
>


<
<
<
<







 







>
>
>
>
>
>
>
>


>
|



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




|

>
>
>
>
>

|
<
<
>







 







|




>

>
>
>
>
>
>

|
<
>
>
|

|







 







|






|
|
|
|













|











|








|


|



|
>
>
>
>
>
|


|
|










>
>







 







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







 







|







|





|

|


|

|


<













<







 







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







 







<







 







<







 







<
<







 







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







 







|
|
>
>

>







 







>
>
>


>

<
>







 







|
<

|



|





|
>




>
>





|
<







 







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






|
|
|
|
|
|
|
|
>



|
|
<




|




<
<
<
<
<
<
<
<
<
<











>







 







<







 







|
<
<
<
<







 







|


>








>










>
>
>
|
|
|
|
|
|
|
>







 







<
<
<
<
<
|







 







>
|
>







 







>







 







>








240
241
242
243
244
245
246


247
248
249
250
251
252
253
...
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
....
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
....
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665




1666
1667
1668
1669









1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681



1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697

1698

1699





1700
1701

1702
1703
1704
1705
1706
1707

1708
1709
1710
1711


1712
1713






1714
1715
1716





1717



1718






1719


1720


1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750





1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
....
2883
2884
2885
2886
2887
2888
2889

2890
2891
2892
2893
2894
2895
2896
....
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933




2934
2935
2936
2937
2938
2939
2940
....
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964




















2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977


2978
2979
2980
2981
2982
2983
2984
2985
....
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070

3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
....
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
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
....
3238
3239
3240
3241
3242
3243
3244

3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255







3256
3257
3258
3259
3260
3261
3262
....
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361

3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374

3375
3376
3377
3378
3379
3380
3381
....
3793
3794
3795
3796
3797
3798
3799












3800
3801
3802
3803
3804
3805
3806
....
3815
3816
3817
3818
3819
3820
3821

3822
3823
3824
3825
3826
3827
3828
....
3829
3830
3831
3832
3833
3834
3835

3836
3837
3838
3839
3840
3841
3842
....
3848
3849
3850
3851
3852
3853
3854


3855
3856
3857
3858
3859
3860
3861
....
3916
3917
3918
3919
3920
3921
3922

































































































3923
3924
3925
3926
3927
3928
3929
3930
....
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
....
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995

3996
3997
3998
3999
4000
4001
4002
4003
....
4010
4011
4012
4013
4014
4015
4016
4017

4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042

4043
4044
4045
4046
4047
4048
4049
....
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
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
....
4342
4343
4344
4345
4346
4347
4348

4349
4350
4351
4352
4353
4354
4355
....
4659
4660
4661
4662
4663
4664
4665
4666




4667
4668
4669
4670
4671
4672
4673
....
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
....
5011
5012
5013
5014
5015
5016
5017





5018
5019
5020
5021
5022
5023
5024
5025
....
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
....
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
....
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
** But if the table is the right table of a left join, WhereLevel.wsFlags
** is set to WO_IN|WO_EQ.  The WhereLevel.wsFlags field can then be used as
** the "op" parameter to findTerm when we are resolving equality constraints.
** ISNULL constraints will then not be used on the right table of a left
** join.  Tickets #2177 and #2189.
*/


#define WHERE_COLUMN_EQ    0x00010000  /* x=EXPR or x IN (...) or x IS NULL */
#define WHERE_COLUMN_RANGE 0x00020000  /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN    0x00040000  /* x IN (...) */
#define WHERE_COLUMN_NULL  0x00080000  /* x IS NULL */
#define WHERE_INDEXED      0x000f0000  /* Anything that uses an index */
#define WHERE_NOT_FULLSCAN 0x100f3000  /* Does not do a full table scan */
#define WHERE_IN_ABLE      0x000f1000  /* Able to support an IN operator */
................................................................................
  WhereClause *pWC,     /* The WHERE clause to be searched */
  int iCur,             /* Cursor number of LHS */
  int iColumn,          /* Column number of LHS */
  Bitmask notReady,     /* RHS must not overlap with this mask */
  u32 op,               /* Mask of WO_xx values describing operator */
  Index *pIdx           /* Must be compatible with this index, if not NULL */
){
  sqlite4 *db = pWC->pParse->db;  /* Database handle */
  WhereTerm *pTerm;
  int k;

  assert( iCur>=0 );
  op &= WO_ALL;
  for(; pWC; pWC=pWC->pOuter){
    for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
      if( pTerm->leftCursor==iCur
         && (pTerm->prereqRight & notReady)==0
         && pTerm->u.leftColumn==iColumn
         && (pTerm->eOperator & op)!=0
      ){
        if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
          Table *pTab = pIdx->pTable;
          const char *zColl;      /* Collation sequence used by index */
          CollSeq *pColl;         /* Collation sequence used by expression */
          Expr *pX = pTerm->pExpr;


          int j;
          Parse *pParse = pWC->pParse;
  
          if( !sqlite4IndexAffinityOk(pX, pTab->aCol[iColumn].affinity) ){
            continue;
          }
  
          /* Figure out the collation sequence used by expression pX. Store

          ** this in pColl. Also the collation sequence used by the index.
          ** Store this one in zColl.  */
          assert(pX->pLeft);
          pColl = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
          assert( pParse->nErr || (pColl && pColl->enc==pIdx->pSchema->enc)  );

          for(j=0; pIdx->aiColumn[j]!=iColumn && j<pIdx->nColumn; j++);
          if( j>=pIdx->nColumn ){
            zColl = pTab->aCol[iColumn].zColl;
          }else{
            zColl = pIdx->azColl[j];
          }


          /* If the collation sequence used by the index is not the same as
          ** that used by the expression, then this term is not a match.  */
          if( pColl!=sqlite4FindCollSeq(db, ENC(db), zColl, 0) ) continue;
        }
        return pTerm;
      }
    }
  }
  return 0;
}
................................................................................

/* Forward reference */
static void exprAnalyze(SrcList*, WhereClause*, int);

/*
** Call exprAnalyze on all terms in a WHERE clause.  
**
** Note that exprAnalyze() might add new virtual terms onto the end of 
** the WHERE clause.  We do not want to analyze these virtual terms, so 
** start analyzing at the end and work forward so that the added virtual 
** terms are never processed.
*/
static void exprAnalyzeAll(
  SrcList *pTabList,       /* the FROM clause */
  WhereClause *pWC         /* the WHERE clause to be analyzed */
){
  int i;
  for(i=pWC->nTerm-1; i>=0; i--){
................................................................................
      return 1;
    }
  }

  return 0;
}


/*
** Return the table column number of the iIdxCol'th field in the index
** keys used by index pIdx, including any appended PRIMARY KEY fields.
** If there is no iIdxCol'th field in index pIdx, return -2.
**
** Example:
**
**   CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
**   CREATE INDEX i1 ON t1(c);
**
** Index i1 in the example above consists of three fields - the indexed
** field "c" followed by the two primary key fields. The automatic PRIMARY
** KEY index consists of two fields only.
*/
static int idxColumnNumber(Index *pIdx, Index *pPk, int iIdxCol){
  int iRet = -2;
  if( iIdxCol<pIdx->nColumn ){
    iRet = pIdx->aiColumn[iIdxCol];
  }else if( iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
    iRet = pPk->aiColumn[iIdxCol - pIdx->nColumn];
  }
  return iRet;
}

/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
** left-most table in the FROM clause of that same SELECT statement and
................................................................................
  Index *pIdx,            /* The index we are testing */
  int base,               /* Cursor number for the table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int nEqCol,             /* Number of index columns with == constraints */
  int wsFlags,            /* Index usages flags */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  sqlite4 *db = pParse->db;       /* Database handle */
  int sortOrder = 0;              /* XOR of index and ORDER BY sort direction */
  int nTerm;                      /* Number of ORDER BY terms */
  int iTerm;                      /* Used to iterate through nTerm terms */
  int iNext = nEqCol;             /* Index of next unmatched column in index */
  int nIdxCol;                    /* Number of columns in index, incl. PK */
  Index *pPk;
  Table *pTab;

  if( !pOrderBy ) return 0;
  if( wsFlags & WHERE_COLUMN_IN ) return 0;
  if( pIdx->bUnordered ) return 0;

  pTab = pIdx->pTable;
  pPk = sqlite4FindPrimaryKey(pTab, 0);
  nTerm = pOrderBy->nExpr;
  nIdxCol = pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn);

  assert( nTerm>0 );
  assert( pIdx && pIdx->zName );





  for(iTerm=0; iTerm<nTerm; iTerm++){
    struct ExprList_item *pTerm;  /* iTerm'th term of ORDER BY clause */
    int iIdxCol;                  /* Index of column in index records */










    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
    CollSeq *pColl;    /* The collating sequence of pExpr */
    int termSortOrder; /* Sort order for this term */
    int iColumn;       /* The i-th column of the index.  -1 for rowid */

    const char *zColl; /* Name of the collating sequence for i-th index term */

    /* Can not use an index sort on anything that is not a column in the
    ** left-most table of the FROM clause. Break out of the loop if this
    ** expression is anything other than that. */
    pTerm = &pOrderBy->a[iTerm];
    pExpr = pTerm->pExpr;
    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ) break;



    iColumn = pExpr->iColumn;

    /* Check that column iColumn is a part of the index. If it is not, then
    ** this index may not be used as a sorting index. This block also checks
    ** that column iColumn is either the iNext'th column of the index, or
    ** else one of the nEqCol columns that the index guarantees will be 
    ** constant.  */
    for(iIdxCol=0; iIdxCol<nIdxCol; iIdxCol++){
      if( idxColumnNumber(pIdx, pPk, iIdxCol)==iColumn ) break;
    }
    if( iIdxCol==nIdxCol || (iIdxCol>=nEqCol && iIdxCol!=iNext) ) break;

    /* Check that the collation sequence used by the expression is the same
    ** as the collation sequence used by the index. If not, this is not a
    ** sorting index.  */
    pColl = sqlite4ExprCollSeq(pParse, pExpr);

    if( !pColl ) pColl = db->pDfltColl;

    if( iIdxCol<pIdx->nColumn ){





      zColl = pIdx->azColl[iIdxCol];
    }else{

      zColl = pTab->aCol[iColumn].zColl;
    }
    if( pColl!=sqlite4FindCollSeq(db, ENC(db), zColl, 0) ) break;

    if( iIdxCol==iNext ){
      u8 reqSortOrder;

      u8 idxSortOrder = SQLITE_SO_ASC;
      if( iIdxCol<pIdx->nColumn ) idxSortOrder = pIdx->aSortOrder[iIdxCol];
      assert( idxSortOrder==SQLITE_SO_ASC || idxSortOrder==SQLITE_SO_DESC );



      reqSortOrder = (idxSortOrder ^ pTerm->sortOrder);
      if( iNext==nEqCol ){






        sortOrder = reqSortOrder;
      }else if( sortOrder!=reqSortOrder ){
        break;





      }



      iNext++;






    }





#if 0
    if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
      /* If the indexed column is the primary key and everything matches
      ** so far and none of the ORDER BY terms to the right reference other
      ** tables in the join, then we are assured that the index can be used 
      ** to sort because the primary key is unique and so none of the other
      ** columns will make any difference
      */
      j = nTerm;
    }
#endif
  }

  *pbRev = sortOrder!=0;

  if( iTerm>=nTerm ){
    /* All terms of the ORDER BY clause are covered by this index. The
    ** index can therefore be used for sorting.  */
    return 1;
  }

  if( pIdx->onError!=OE_None
   && iNext>=pIdx->nColumn 
   && (wsFlags & WHERE_COLUMN_NULL)==0
   && !referencesOtherTables(pOrderBy, pMaskSet, iTerm, base) 
  ){

    if( iNext==nIdxCol ){
      /* All columns indexed by this UNIQUE index, and all PK columns are
      ** are matched by a prefix of the ORDER BY clause. And since the PK





      ** columns are guaranteed to be unique and NOT NULL, there is no way
      ** for the trailing ORDER BY terms to affect the sort order. Therefore,
      ** we have a sorting index.  */
      return 1;
    }else{
      int i;
      for(i=nEqCol; i<pIdx->nColumn; i++){
        int iCol = pIdx->aiColumn[i];
        if( iCol>=0 && pTab->aCol[iCol].notNull==0 ) break;
      }

      /* All columns indexed by this UNIQUE index are matched by a prefix
      ** of the ORDER BY clause. And there is reason to believe that none
      ** of the expressions in the ORDER BY prefix will evalulate to NULL.
      ** The index may be used for sorting in this case too since it is
      ** guaranteed that none of the trailing, unmatched ORDER BY terms 
      ** affect the sort order.  */
      return (i>=pIdx->nColumn);
    }
  }

  return 0;
}

/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact.  This is only used for estimating
** the total cost of performing operations with O(logN) or O(NlogN)
................................................................................
    *pnRow = nRowEst;
    WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
  }
  return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */


/*
** Find the best query plan for accessing a particular table.  Write the
** best query plan and its cost into the WhereCost object supplied as the
** last parameter.
**
** The lowest cost plan wins.  The cost is an estimate of the amount of
** CPU and disk I/O needed to process the requested result.
................................................................................
  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 */
  Index *pPk;                 /* Primary Key index */
  int eqTermMask;             /* Current mask of valid equality operators */
  int idxEqTermMask;          /* Index mask of valid equality operators */





  /* 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
  ** use an index to satisfy IS NULL constraints on that table.  This is
................................................................................
  */
  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
  eqTermMask = idxEqTermMask;
  pFirst = pSrc->pTab->pIndex;
#endif
  pPk = sqlite4FindPrimaryKey(pSrc->pTab, 0);

  /* 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;
................................................................................
    int nEq;                      /* Number of == or IN terms matching index */
    int bInEst = 0;               /* True if "x IN (SELECT...)" seen */
    int nInMul = 1;               /* Number of distinct equalities to lookup */
    double rangeDiv = (double)1;  /* Estimated reduction in search space */
    int nBound = 0;               /* Number of range constraints seen */
    int bSort = !!pOrderBy;       /* True if external sort required */
    int bDist = !!pDistinct;      /* True if index cannot help with DISTINCT */
    int bLookup = 0;              /* True if not the PK index */
    WhereTerm *pTerm;             /* A single term of the WHERE clause */
#ifdef SQLITE_ENABLE_STAT3
    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
#endif
    int nCol = pProbe->nColumn;   /* Total columns in index record */

    /* Unless pProbe is the primary key index, then the encoded PK column 
    ** values are at the end of each record. Set variable nCol to the total
    ** number of columns encoded into each index record, including the PK  
    ** columns.  */
    if( pProbe!=pPk ) nCol += pPk->nColumn;

    /* Determine the values of nEq and nInMul */
    for(nEq=0; nEq<nCol; nEq++){

      int iCol;                   /* Table column of nEq'th index field */
      iCol = idxColumnNumber(pProbe, pPk, nEq);
      pTerm = findTerm(pWC, iCur, iCol, notReady, eqTermMask, pProbe);
      if( pTerm==0 ) break;
      wsFlags |= WHERE_COLUMN_EQ;
      testcase( pTerm->pWC!=pWC );
      if( pTerm->eOperator & WO_IN ){
        Expr *pExpr = pTerm->pExpr;
        wsFlags |= WHERE_COLUMN_IN;
        if( ExprHasProperty(pExpr, EP_xIsSelect) ){
          /* "x IN (SELECT ...)":  Assume the SELECT returns 25 rows */
          nInMul *= 25;
................................................................................
    ** at most a single row. In this case set the WHERE_UNIQUE flag to 
    ** indicate this to the caller.
    **
    ** Otherwise, if the search may find more than one row, test to see if
    ** there is a range constraint on indexed column (nEq+1) that can be 
    ** optimized using the index. 
    */
    if( nEq>=pProbe->nColumn && pProbe->onError!=OE_None ){
      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 = idxColumnNumber(pProbe, pPk, 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 );
        }
        if( pBtm ){
          nBound++;
          wsFlags |= WHERE_BTM_LIMIT;
          used |= pBtm->prereqRight;
          testcase( pBtm->pWC!=pWC );
        }
        wsFlags |= WHERE_COLUMN_RANGE;
      }
    }

    /* If there is an ORDER BY clause and the index being considered will
    ** naturally scan rows in the required order, set the appropriate flags
    ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
    ** will scan rows in a different order, set the bSort variable.  */
    if( isSortingIndex(
          pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev)
    ){
      bSort = 0;
      wsFlags |= WHERE_COLUMN_RANGE|WHERE_ORDERBY;
      wsFlags |= (rev ? WHERE_REVERSE : 0);
    }

    /* If there is a DISTINCT qualifier and this index will scan rows in
    ** 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_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;
      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 */

    eqTermMask = idxEqTermMask;
  }

  /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
  ** is set, then reverse the order that the index will be scanned
  ** in. This is used for application testing, to help find cases
  ** where application behaviour depends on the (undefined) order that
  ** SQLite outputs rows in in the absence of an ORDER BY clause.  */
  if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
    pCost->plan.wsFlags |= WHERE_REVERSE;
  }

  assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );

  assert( pSrc->pIndex==0 
       || pCost->plan.u.pIdx==0 
       || pCost->plan.u.pIdx==pSrc->pIndex 
  );

  WHERETRACE(("best index is: %s\n", 
    ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : 
................................................................................
          ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
          ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
          ((flags & WHERE_TEMP_INDEX)?"":" "),
          ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName),
          zWhere
      );
      sqlite4DbFree(db, zWhere);












    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
      sqlite4_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
      zMsg = sqlite4MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
                  pVtabIdx->idxNum, pVtabIdx->idxStr);
    }
................................................................................
    sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE_OMIT_EXPLAIN */


/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
static Bitmask codeOneLoopStart(
  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
  int iLevel,          /* Which level of pWInfo->a[] should be coded */
................................................................................
  u16 wctrlFlags,      /* One of the WHERE_* flags defined in sqliteInt.h */
  Bitmask notReady,    /* Which tables are currently available */
  Expr *pWhere         /* Complete WHERE clause */
){
  int j, k;            /* Loop counters */
  int iCur;            /* The VDBE cursor for the table */
  int addrNxt;         /* Where to jump to continue with the next IN case */

  int bRev;            /* True if we need to scan in reverse order */
  WhereLevel *pLevel;  /* The where level to be coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  Parse *pParse;                  /* Parsing context */
  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
................................................................................
  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = pWInfo->pWC;
  pLevel = &pWInfo->a[iLevel];
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;



  /* Create labels for the "break" and "continue" instructions
  ** for the current loop.  Jump to addrBrk to break out of a loop.
  ** Jump to cont to go immediately to the next iteration of the
  ** loop.
  **
  ** When there is an IN operator, we also have a "addrNxt" label that
................................................................................
    pLevel->p1 = iCur;
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2);
    sqlite4ExprCachePop(pParse, 1);
  }else
#endif /* SQLITE_OMIT_VIRTUALTABLE */


































































































  if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
    /* Case 3: A scan using an index.
    **
    **         The WHERE clause may contain zero or more equality 
    **         terms ("==" or "IN" operators) that refer to the N
    **         left-most columns of the index. It may also contain
    **         inequality constraints (>, <, >= or <=) on the indexed
    **         column that immediately follows the N equalities. Only 
................................................................................
      OP_SeekGt,           /* 4: (start_constraints  && !startEq && !bRev) */
      OP_SeekLt,           /* 5: (start_constraints  && !startEq &&  bRev) */
      OP_SeekGe,           /* 6: (start_constraints  &&  startEq && !bRev) */
      OP_SeekLe            /* 7: (start_constraints  &&  startEq &&  bRev) */
    };
    static const u8 aEndOp[] = {
      OP_Noop,             /* 0: (!end_constraints) */
      OP_IdxGE,            /* 1: (end_constraints && !endEq && !bRev) */
      OP_IdxLE,            /* 2: (end_constraints && !endEq &&  bRev) */
      OP_IdxGT,            /* 3: (end_constraints &&  endEq && !bRev) */
      OP_IdxLT             /* 4: (end_constraints &&  endEq &&  bRev) */
    };

    int nEq = pLevel->plan.nEq;  /* Number of == or IN terms */
    int isMinQuery = 0;          /* If this is an optimized SELECT min(x).. */
    int regBase;                 /* Base register holding constraint values */
    int r1;                      /* Temp register */
    WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
    WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
    int startEq;                 /* True if range start uses ==, >= or <= */
................................................................................
    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 */
    int iIneq;                   /* The table column subject to inequality */
    Index *pPk;                  /* Primary key index on same table as pIdx */

    pIdx = pLevel->plan.u.pIdx;
    pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
    iIdxCur = pLevel->iIdxCur;

    iIneq = idxColumnNumber(pIdx, pPk, nEq);

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
    ** query, then the caller will only allow the loop to run for
    ** a single iteration. This means that the first row returned
    ** should not have a NULL value stored in 'x'. If column 'x' is
    ** the first one after the nEq equality constraints in the index,
................................................................................
      /* assert( pOrderBy->nExpr==1 ); */
      /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
      isMinQuery = 1;
      nExtraReg = 1;
    }

    /* Find any inequality constraint terms for the start and end 
    ** of the range.  */

    if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
      pRangeEnd = findTerm(pWC, iCur, iIneq, notReady, (WO_LT|WO_LE), pIdx);
      nExtraReg = 1;
    }
    if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
      pRangeStart = findTerm(pWC, iCur, iIneq, notReady, (WO_GT|WO_GE), pIdx);
      nExtraReg = 1;
    }

    /* Generate code to evaluate all constraint terms using == or IN
    ** and store the values of those terms in an array of registers
    ** starting at regBase. Ensure that nExtraReg registers are allocated
    ** immediately following the array.
    */
    regBase = codeAllEqualityTerms(
        pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff
    );
    assert( (regBase+nEq+nExtraReg-1)<=pParse->nMem );

    zEndAff = sqlite4DbStrDup(pParse->db, zStartAff);
    addrNxt = pLevel->addrNxt;

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).  */

    if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
     || (bRev && pIdx->nColumn==nEq)
    ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
    }

    testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
................................................................................
    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.  */
    assert( (endEq==0 || endEq==1) );
    op = aEndOp[(pRangeEnd || nEq) * (1 + (endEq+endEq) + bRev)];
    testcase( op==OP_Noop );
    testcase( op==OP_IdxGE );
    testcase( op==OP_IdxLT );
    testcase( op==OP_IdxLE );
    testcase( op==OP_IdxGT );

    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_MakeIdxKey */
      regEndKey = ++pParse->nMem;
      sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdxCur, regBase, regEndKey);
      sqlite4VdbeChangeP4(v, -1, (char *)nConstraint, P4_INT32);
    }

    sqlite4DbFree(pParse->db, zStartAff);
    sqlite4DbFree(pParse->db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);

    if( op!=OP_Noop ){
      sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regEndKey, nConstraint);
    }

    /* Seek the PK cursor, if required */
    disableTerm(pLevel, pRangeStart);
    disableTerm(pLevel, pRangeEnd);
    if( pIdx->eIndexType!=SQLITE_INDEX_PRIMARYKEY ){
      sqlite4VdbeAddOp3(v, OP_SeekPk, iCur, 0, iIdxCur);
    }

    /* If there are inequality constraints, check that the value
    ** of the table column that the inequality constrains is not NULL.
    ** If it is, jump to the next iteration of the loop.  */

    r1 = sqlite4GetTempReg(pParse);
    testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
    testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
    if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
      sqlite4VdbeAddOp3(v, OP_Column, iCur, pIdx->aiColumn[nEq], r1);
      sqlite4VdbeAddOp2(v, OP_IsNull, r1, addrCont);
    }
    sqlite4ReleaseTempReg(pParse, r1);











    /* Record the instruction used to terminate the loop. Disable 
    ** WHERE clause terms made redundant by the index range scan.
    */
    if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
      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:
................................................................................
  {
    /* Case 5:  There is no usable index.  We must do a complete
    **          scan of the entire table.
    */
    static const u8 aStep[] = { OP_Next, OP_Prev };
    static const u8 aStart[] = { OP_Rewind, OP_Last };
    assert( bRev==0 || bRev==1 );

    pLevel->op = aStep[bRev];
    pLevel->p1 = iCur;
    pLevel->p2 = 1 + sqlite4VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
    pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
  }
  notReady &= ~getMask(pWC->pMaskSet, iCur);

................................................................................
      Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor);
      assert( (m-1)==toTheLeft );
      toTheLeft |= m;
    }
  }
#endif

  /* Analyze all of the subexpressions. */




  exprAnalyzeAll(pTabList, pWC);
  if( db->mallocFailed ){
    goto whereBeginError;
  }

  /* Check if the DISTINCT qualifier, if there is one, is redundant. 
  ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
................................................................................
      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;

................................................................................
        nQPlan += 2;
      }else{
        memcpy(&sqlite4_query_plan[nQPlan], z, n);
        nQPlan += n;
      }
      sqlite4_query_plan[nQPlan++] = ' ';
    }





    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
      n = sqlite4Strlen30(pLevel->plan.u.pIdx->zName);
      if( n+nQPlan < sizeof(sqlite4_query_plan)-2 ){
        memcpy(&sqlite4_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
        nQPlan += n;
        sqlite4_query_plan[nQPlan++] = ' ';
      }
    }else{
................................................................................
     && (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
................................................................................
    ** 
    ** Calls to the code generator in between sqlite4WhereBegin and
    ** sqlite4WhereEnd will have created code that references the table
    ** directly.  This loop scans all that code looking for opcodes
    ** that reference the table and converts them into opcodes that
    ** reference the index.
    */
#if 0
    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){
      int k, j, last;
      VdbeOp *pOp;
      Index *pIdx = pLevel->plan.u.pIdx;

      assert( pIdx!=0 );
      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
................................................................................
               || j<pIdx->nColumn );
        }else if( pOp->opcode==OP_Rowid ){
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowid;
        }
      }
    }
#endif
  }

  /* Final cleanup
  */
  pParse->nQueryLoop = pWInfo->savedNQueryLoop;
  whereInfoFree(db, pWInfo);
  return;
}

Changes to test/conflict.test.

49
50
51
52
53
54
55
56
57
58
59
60
61


62
63
64
65
66
67
68
..
95
96
97
98
99
100
101
102
103
104
105
106
107


108
109
110
111
112
113
114
...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
308
309
310
311
312
313
314




315
316
317
318
319
320
321
322
323
324
...
330
331
332
333
334
335
336

337
338
339
340
341
342
343
...
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
...
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
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
...
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
...
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
...
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
...
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
...
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
...
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
...
805
806
807
808
809
810
811
812
813
814
  4 REPLACE                 0 4   1  0
  5 {INSERT OR FAIL}        1 {}  1  0
  6 {INSERT OR ABORT}       1 {}  1  0
  7 {INSERT OR ROLLBACK}    1 {}  {} 0
} {
  do_test conflict-1.$i {
    set ::sqlite_opentemp_count 0
    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 


      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    set r3 $::sqlite_opentemp_count
    list $r0 $r1 $r2 $r3
................................................................................
  3 {INSERT OR REPLACE}     0 4   1
  4 REPLACE                 0 4   1
  5 {INSERT OR FAIL}        1 {}  1
  6 {INSERT OR ABORT}       1 {}  1
  7 {INSERT OR ROLLBACK}    1 {}  {}
} {
  do_test conflict-2.$i {
    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 


      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
................................................................................
  8 IGNORE   {INSERT OR REPLACE}     0 4   1
  9 FAIL     {INSERT OR IGNORE}      0 3   1
 10 ABORT    {INSERT OR REPLACE}     0 4   1
 11 ROLLBACK {INSERT OR IGNORE }     0 3   1
} {
  do_test conflict-4.$i {
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
}

................................................................................
} {
  if {$t0} {set t1 {column a is not unique}}
  if {[info exists TEMP_STORE] && $TEMP_STORE==3} {
    set t3 0
  } else {
    set t3 [expr {$t3+$t4}]
  }




  do_test conflict-6.$i {
    db close
    sqlite4 db test.db 
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    execsql {pragma temp_store=file}
    set ::sqlite_opentemp_count 0
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
      INSERT INTO t1 SELECT * FROM t2;
................................................................................
    }]} r1]
    catch {execsql {COMMIT}}
    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
    set r2 [execsql {SELECT x FROM t3}]
    list $r0 $r1 $r2 $::sqlite_opentemp_count
  } [list $t0 $t1 $t2 $t3]
}


# Test to make sure a lot of IGNOREs don't cause a stack overflow
#
do_test conflict-7.1 {
  execsql {
    DROP TABLE t1;
    DROP TABLE t2;
................................................................................
  }
  execsql {
    SELECT count(*), min(a), max(b) FROM t1;
  }
} {50 1 51}
do_test conflict-7.2 {
  execsql {
    PRAGMA count_changes=on;
    UPDATE OR IGNORE t1 SET a=1000;
  }
} {1}
do_test conflict-7.2.1 {
  db changes
} {1}
do_test conflict-7.3 {
  execsql {
    SELECT b FROM t1 WHERE a=1000;
  }
} {2}
do_test conflict-7.4 {
  execsql {
    SELECT count(*) FROM t1;
  }
} {50}
do_test conflict-7.5 {
  execsql {
    PRAGMA count_changes=on;
    UPDATE OR REPLACE t1 SET a=1001;
  }
} {50}
do_test conflict-7.5.1 {
  db changes
} {50}
do_test conflict-7.6 {
  execsql {
    SELECT b FROM t1 WHERE a=1001;
  }
} {51}
do_test conflict-7.7 {
  execsql {
    SELECT count(*) FROM t1;
  }
} {1}
................................................................................
  execsql {
    DELETE FROM t1;
    INSERT INTO t1 VALUES(1,2);
  }
  execsql {
    INSERT OR IGNORE INTO t1 VALUES(2,3);
  }
} {1}
do_test conflict-8.1.1 {
  db changes
} {1}
do_test conflict-8.2 {
  execsql {
    INSERT OR IGNORE INTO t1 VALUES(2,4);
  }
} {0}
do_test conflict-8.2.1 {
  db changes
} {0}
do_test conflict-8.3 {
  execsql {
    INSERT OR REPLACE INTO t1 VALUES(2,4);
  }
} {1}
do_test conflict-8.3.1 {
  db changes
} {1}
do_test conflict-8.4 {
  execsql {
    INSERT OR IGNORE INTO t1 SELECT * FROM t1;
  }
} {0}
do_test conflict-8.4.1 {
  db changes
} {0}
do_test conflict-8.5 {
  execsql {
    INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1;
  }
} {2}
do_test conflict-8.5.1 {
  db changes
} {2}
do_test conflict-8.6 {
  execsql {
    INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1;
  }
} {3}
do_test conflict-8.6.1 {
  db changes
} {3}

integrity_check conflict-8.99

do_test conflict-9.1 {
  execsql {
    PRAGMA count_changes=0;
    CREATE TABLE t2(
      a INTEGER UNIQUE ON CONFLICT IGNORE,
      b INTEGER UNIQUE ON CONFLICT FAIL,
      c INTEGER UNIQUE ON CONFLICT REPLACE,
      d INTEGER UNIQUE ON CONFLICT ABORT,
      e INTEGER UNIQUE ON CONFLICT ROLLBACK
    );
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(1,3,3,3,3);
    SELECT * FROM t2;
  }
} {0 {1 1 1 1 1 2 2 2 2 2}}
do_test conflict-9.4 {
  catchsql {
    UPDATE t2 SET a=a+1 WHERE a=1;
    SELECT * FROM t2;
  }
} {0 {1 1 1 1 1 2 2 2 2 2}}
do_test conflict-9.5 {
  catchsql {
    INSERT INTO t2 VALUES(3,1,3,3,3);
    SELECT * FROM t2;
  }
} {1 {column b is not unique}}
do_test conflict-9.6 {
  catchsql {
    UPDATE t2 SET b=b+1 WHERE b=1;
    SELECT * FROM t2;
  }
} {1 {column b is not unique}}
do_test conflict-9.7 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {2}
do_test conflict-9.9 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
    UPDATE t2 SET b=b+1 WHERE b=1;
    SELECT * FROM t2;
  }
} {1 {column b is not unique}}
do_test conflict-9.10 {
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {3}
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(3,3,3,1,3);
    SELECT * FROM t2;
  }
} {1 {column d is not unique}}
do_test conflict-9.12 {
  catchsql {
    UPDATE t2 SET d=d+1 WHERE d=1;
    SELECT * FROM t2;
  }
} {1 {column d is not unique}}
do_test conflict-9.13 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {4}
do_test conflict-9.15 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
    UPDATE t2 SET d=d+1 WHERE d=1;
    SELECT * FROM t2;
  }
} {1 {column d is not unique}}
do_test conflict-9.16 {
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {5}
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(3,3,3,3,1);
    SELECT * FROM t2;
  }
} {1 {column e is not unique}}
do_test conflict-9.18 {
  catchsql {
    UPDATE t2 SET e=e+1 WHERE e=1;
    SELECT * FROM t2;
  }
} {1 {column e is not unique}}
do_test conflict-9.19 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
  catch {execsql {COMMIT}}
  execsql {SELECT * FROM t3}
} {5}
do_test conflict-9.21 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
    UPDATE t2 SET e=e+1 WHERE e=1;
    SELECT * FROM t2;
  }
} {1 {column e is not unique}}
do_test conflict-9.22 {
  catch {execsql {COMMIT}}
  execsql {SELECT * FROM t3}
} {5}
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(3,3,1,3,3);
    SELECT * FROM t2;
  }
} {0 {2 2 2 2 2 3 3 1 3 3}}
do_test conflict-9.24 {
  catchsql {
    UPDATE t2 SET c=c-1 WHERE c=2;
    SELECT * FROM t2;
  }
} {0 {2 2 1 2 2}}
do_test conflict-9.25 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
#
do_test conflict-11.1 {
  execsql {
    -- Create a database object (pages 2, 3 of the file)
    BEGIN;
      CREATE TABLE abc(a UNIQUE, b, c);
      INSERT INTO abc VALUES(1, 2, 3);
      INSERT INTO abc VALUES(4, 5, 6);
      INSERT INTO abc VALUES(7, 8, 9);
    COMMIT;
  }

  
  # Set a small cache size so that changes will spill into
  # the database file.  
  execsql {
    PRAGMA cache_size = 10;
  }
  
................................................................................
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      DELETE FROM abc WHERE a = 4;
  }

  # Execute a statement that does a statement rollback due to
  # a constraint failure.
  #
  catchsql {
    INSERT INTO abc SELECT 10, 20, 30 FROM def;
................................................................................
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      DELETE FROM abc WHERE a = 4;
  }
  catchsql {
    INSERT INTO abc SELECT 10, 20, 30 FROM def;
  }
  execsql {
    ROLLBACK;
    SELECT * FROM abc;
  }
} {1 2 3 4 5 6 7 8 9}

# Repeat test conflict-11.1 but this time commit.
#
do_test conflict-11.5 {
  execsql {
    BEGIN;
      -- Make sure the pager is in EXCLUSIVE state.
      CREATE TABLE def(d, e, f);
................................................................................
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      DELETE FROM abc WHERE a = 4;
  }
  catchsql {
    INSERT INTO abc SELECT 10, 20, 30 FROM def;
  }
  execsql {
    COMMIT;
    SELECT * FROM abc;
................................................................................
    SELECT * FROM t5;
  }
} {1 one 2 two}
do_test conflict-12.3 {
  catchsql {
    UPDATE t5 SET a=a+1 WHERE a=1;
  }
} {1 {PRIMARY KEY must be unique}}
do_test conflict-12.4 {
  execsql {
    UPDATE OR REPLACE t5 SET a=a+1 WHERE a=1;
    SELECT * FROM t5;
  }
} {2 one}


# Ticket [c38baa3d969eab7946dc50ba9d9b4f0057a19437]
# REPLACE works like ABORT on a CHECK constraint.
#
do_test conflict-13.1 {
  execsql {
    CREATE TABLE t13(a CHECK(a!=2));
................................................................................
do_test conflict-13.2 {
  execsql {
    REPLACE INTO t13 VALUES(3);
    COMMIT;
    SELECT * FROM t13;
  }
} {1 3}


finish_test







|





>
>







 







|





>
>







 







|






|
|







 







>
>
>
>

<
<







 







>







 







<


|





|









<


|





|







 







|







|







|







|







|







|








<







 







|











|







 







|







 







|







 







|







 







|







 







|







 







|







 







|
|


<







 







|







 







|









>







 







|







 







|






<







 








<

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
...
312
313
314
315
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
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
...
408
409
410
411
412
413
414
415
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
...
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
...
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
...
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
...
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
...
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
...
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
...
652
653
654
655
656
657
658
659
660
661
662

663
664
665
666
667
668
669
...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
...
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
...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
...
780
781
782
783
784
785
786
787
788
789
790
791
792
793

794
795
796
797
798
799
800
...
808
809
810
811
812
813
814
815

816
  4 REPLACE                 0 4   1  0
  5 {INSERT OR FAIL}        1 {}  1  0
  6 {INSERT OR ABORT}       1 {}  1  0
  7 {INSERT OR ROLLBACK}    1 {}  {} 0
} {
  do_test conflict-1.$i {
    set ::sqlite_opentemp_count 0
    execsql {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
    }
    set r0 [catch {execsql [subst {
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    set r3 $::sqlite_opentemp_count
    list $r0 $r1 $r2 $r3
................................................................................
  3 {INSERT OR REPLACE}     0 4   1
  4 REPLACE                 0 4   1
  5 {INSERT OR FAIL}        1 {}  1
  6 {INSERT OR ABORT}       1 {}  1
  7 {INSERT OR ROLLBACK}    1 {}  {}
} {
  do_test conflict-2.$i {
    execsql {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
    }
    set r0 [catch {execsql [subst {
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
................................................................................
  8 IGNORE   {INSERT OR REPLACE}     0 4   1
  9 FAIL     {INSERT OR IGNORE}      0 3   1
 10 ABORT    {INSERT OR REPLACE}     0 4   1
 11 ROLLBACK {INSERT OR IGNORE }     0 3   1
} {
  do_test conflict-4.$i {
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
    }]
    set r0 [catch {execsql "$cmd INTO t1 VALUES(1,2,4)"} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
}

................................................................................
} {
  if {$t0} {set t1 {column a is not unique}}
  if {[info exists TEMP_STORE] && $TEMP_STORE==3} {
    set t3 0
  } else {
    set t3 [expr {$t3+$t4}]
  }

  # Update for SQLite 4: No temporary files ever.
  set t3 0

  do_test conflict-6.$i {


    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    execsql {pragma temp_store=file}
    set ::sqlite_opentemp_count 0
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
      INSERT INTO t1 SELECT * FROM t2;
................................................................................
    }]} r1]
    catch {execsql {COMMIT}}
    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
    set r2 [execsql {SELECT x FROM t3}]
    list $r0 $r1 $r2 $::sqlite_opentemp_count
  } [list $t0 $t1 $t2 $t3]
}


# Test to make sure a lot of IGNOREs don't cause a stack overflow
#
do_test conflict-7.1 {
  execsql {
    DROP TABLE t1;
    DROP TABLE t2;
................................................................................
  }
  execsql {
    SELECT count(*), min(a), max(b) FROM t1;
  }
} {50 1 51}
do_test conflict-7.2 {
  execsql {

    UPDATE OR IGNORE t1 SET a=1000;
  }
} {}
do_test conflict-7.2.1 {
  db changes
} {1}
do_test conflict-7.3 {
  execsql {
    SELECT b FROM t1 WHERE +a=1000;
  }
} {2}
do_test conflict-7.4 {
  execsql {
    SELECT count(*) FROM t1;
  }
} {50}
do_test conflict-7.5 {
  execsql {

    UPDATE OR REPLACE t1 SET a=1001;
  }
} {}
do_test conflict-7.5.1 {
  db changes
} {50}
do_test conflict-7.6 {
  execsql {
    SELECT b FROM t1 WHERE +a=1001;
  }
} {51}
do_test conflict-7.7 {
  execsql {
    SELECT count(*) FROM t1;
  }
} {1}
................................................................................
  execsql {
    DELETE FROM t1;
    INSERT INTO t1 VALUES(1,2);
  }
  execsql {
    INSERT OR IGNORE INTO t1 VALUES(2,3);
  }
} {}
do_test conflict-8.1.1 {
  db changes
} {1}
do_test conflict-8.2 {
  execsql {
    INSERT OR IGNORE INTO t1 VALUES(2,4);
  }
} {}
do_test conflict-8.2.1 {
  db changes
} {0}
do_test conflict-8.3 {
  execsql {
    INSERT OR REPLACE INTO t1 VALUES(2,4);
  }
} {}
do_test conflict-8.3.1 {
  db changes
} {1}
do_test conflict-8.4 {
  execsql {
    INSERT OR IGNORE INTO t1 SELECT * FROM t1;
  }
} {}
do_test conflict-8.4.1 {
  db changes
} {0}
do_test conflict-8.5 {
  execsql {
    INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1;
  }
} {}
do_test conflict-8.5.1 {
  db changes
} {2}
do_test conflict-8.6 {
  execsql {
    INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1;
  }
} {}
do_test conflict-8.6.1 {
  db changes
} {3}

integrity_check conflict-8.99

do_test conflict-9.1 {
  execsql {

    CREATE TABLE t2(
      a INTEGER UNIQUE ON CONFLICT IGNORE,
      b INTEGER UNIQUE ON CONFLICT FAIL,
      c INTEGER UNIQUE ON CONFLICT REPLACE,
      d INTEGER UNIQUE ON CONFLICT ABORT,
      e INTEGER UNIQUE ON CONFLICT ROLLBACK
    );
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(1,3,3,3,3);
    SELECT * FROM t2;
  }
} {0 {1 1 1 1 1 2 2 2 2 2}}
do_test conflict-9.4 {
  catchsql {
    UPDATE t2 SET a=a+1 WHERE +a=1;
    SELECT * FROM t2;
  }
} {0 {1 1 1 1 1 2 2 2 2 2}}
do_test conflict-9.5 {
  catchsql {
    INSERT INTO t2 VALUES(3,1,3,3,3);
    SELECT * FROM t2;
  }
} {1 {column b is not unique}}
do_test conflict-9.6 {
  catchsql {
    UPDATE t2 SET b=b+1 WHERE +b=1;
    SELECT * FROM t2;
  }
} {1 {column b is not unique}}
do_test conflict-9.7 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {2}
do_test conflict-9.9 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
    UPDATE t2 SET b=b+1 WHERE +b=1;
    SELECT * FROM t2;
  }
} {1 {column b is not unique}}
do_test conflict-9.10 {
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {3}
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(3,3,3,1,3);
    SELECT * FROM t2;
  }
} {1 {column d is not unique}}
do_test conflict-9.12 {
  catchsql {
    UPDATE t2 SET d=d+1 WHERE +d=1;
    SELECT * FROM t2;
  }
} {1 {column d is not unique}}
do_test conflict-9.13 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {4}
do_test conflict-9.15 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
    UPDATE t2 SET d=d+1 WHERE +d=1;
    SELECT * FROM t2;
  }
} {1 {column d is not unique}}
do_test conflict-9.16 {
  execsql {COMMIT}
  execsql {SELECT * FROM t3}
} {5}
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(3,3,3,3,1);
    SELECT * FROM t2;
  }
} {1 {column e is not unique}}
do_test conflict-9.18 {
  catchsql {
    UPDATE t2 SET e=e+1 WHERE +e=1;
    SELECT * FROM t2;
  }
} {1 {column e is not unique}}
do_test conflict-9.19 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
  catch {execsql {COMMIT}}
  execsql {SELECT * FROM t3}
} {5}
do_test conflict-9.21 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
    UPDATE t2 SET e=e+1 WHERE +e=1;
    SELECT * FROM t2;
  }
} {1 {column e is not unique}}
do_test conflict-9.22 {
  catch {execsql {COMMIT}}
  execsql {SELECT * FROM t3}
} {5}
................................................................................
  catchsql {
    INSERT INTO t2 VALUES(3,3,1,3,3);
    SELECT * FROM t2;
  }
} {0 {2 2 2 2 2 3 3 1 3 3}}
do_test conflict-9.24 {
  catchsql {
    UPDATE t2 SET c=c-1 WHERE +c=2;
    SELECT * FROM t2;
  }
} {0 {2 2 1 2 2}}
do_test conflict-9.25 {
  catchsql {
    BEGIN;
    UPDATE t3 SET x=x+1;
................................................................................
#
do_test conflict-11.1 {
  execsql {
    -- Create a database object (pages 2, 3 of the file)
    BEGIN;
      CREATE TABLE abc(a UNIQUE, b, c);
      INSERT INTO abc VALUES(1, 2, 3);
      INSert into abc VALUES(4, 5, 6);
      insERT INTO abc VALUES(7, 8, 9);
    COMMIT;
  }

  
  # Set a small cache size so that changes will spill into
  # the database file.  
  execsql {
    PRAGMA cache_size = 10;
  }
  
................................................................................
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      DELETE FROM abc WHERE +a = 4;
  }

  # Execute a statement that does a statement rollback due to
  # a constraint failure.
  #
  catchsql {
    INSERT INTO abc SELECT 10, 20, 30 FROM def;
................................................................................
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      DELETE FROM abc WHERE +a = 4;
  }
  catchsql {
    INSERT INTO abc SELECT 10, 20, 30 FROM def;
  }
  execsql {
    ROLLBACK;
    SELECT * FROM abc;
  }
} {1 2 3 4 5 6 7 8 9}

# Repeat test conflict-11.1 but this time commit.
#
do_test conflict-11.5 {
  execsql {
    BEGIN;
      -- Make sure the pager is in EXCLUSIVE state.
      CREATE TABLE def(d, e, f);
................................................................................
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      INSERT INTO def SELECT * FROM def;
      DELETE FROM abc WHERE +a = 4;
  }
  catchsql {
    INSERT INTO abc SELECT 10, 20, 30 FROM def;
  }
  execsql {
    COMMIT;
    SELECT * FROM abc;
................................................................................
    SELECT * FROM t5;
  }
} {1 one 2 two}
do_test conflict-12.3 {
  catchsql {
    UPDATE t5 SET a=a+1 WHERE a=1;
  }
} {1 {column a is not unique}}
do_test conflict-12.4 {
  execsql {
    UPDATE OR REPLACE t5 SET a=a+1 WHERE a=1;
    SELECT * FROM t5;
  }
} {2 one}


# Ticket [c38baa3d969eab7946dc50ba9d9b4f0057a19437]
# REPLACE works like ABORT on a CHECK constraint.
#
do_test conflict-13.1 {
  execsql {
    CREATE TABLE t13(a CHECK(a!=2));
................................................................................
do_test conflict-13.2 {
  execsql {
    REPLACE INTO t13 VALUES(3);
    COMMIT;
    SELECT * FROM t13;
  }
} {1 3}


finish_test

Changes to test/fkey2.test.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
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
...
212
213
214
215
216
217
218

219
220
221
222
223
224
225
...
274
275
276
277
278
279
280

281
282
283
284
285
286
287
}

#-------------------------------------------------------------------------
# Test structure:
#
# fkey2-1.*: Simple tests to check that immediate and deferred foreign key 
#            constraints work when not inside a transaction.
#            
# fkey2-2.*: Tests to verify that deferred foreign keys work inside
#            explicit transactions (i.e that processing really is deferred).
#
# fkey2-3.*: Tests that a statement transaction is rolled back if an
#            immediate foreign key constraint is violated.
#
# fkey2-4.*: Test that FK actions may recurse even when recursive triggers
#            are disabled.
................................................................................
  4.9  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}
  4.10 "UPDATE t8 SET c=NULL WHERE d=4"   {0 {}}
  4.11 "DELETE FROM t7 WHERE b=1"         {1 {foreign key constraint failed}}
  4.12 "UPDATE t7 SET b = 2"              {1 {foreign key constraint failed}}
  4.13 "UPDATE t7 SET b = 1"              {0 {}}
  4.14 "INSERT INTO t8 VALUES('a', 'b')"  {1 {foreign key constraint failed}}
  4.15 "UPDATE t7 SET b = 5"              {1 {foreign key constraint failed}}
  4.16 "UPDATE t7 SET rowid = 5"          {1 {foreign key constraint failed}}
  4.17 "UPDATE t7 SET a = 10"             {0 {}}

  5.1  "INSERT INTO t9 VALUES(1, 3)"      {1 {no such table: main.nosuchtable}}
  5.2  "INSERT INTO t10 VALUES(1, 3)"     {1 {foreign key mismatch}}
}



do_test fkey2-1.1.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
} {}
foreach {tn zSql res} $FkeySimpleTests {
  do_test fkey2-1.1.$tn { catchsql $zSql } $res
}
drop_all_tables



do_test fkey2-1.2.0 {
  execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
} {}
foreach {tn zSql res} $FkeySimpleTests {
  do_test fkey2-1.2.$tn { catchsql $zSql } $res
}
drop_all_tables




do_test fkey2-1.3.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
  execsql { PRAGMA count_changes = 1 }
} {}
foreach {tn zSql res} $FkeySimpleTests {
  if {$res == "0 {}"} { set res {0 1} }

  do_test fkey2-1.3.$tn { catchsql $zSql } $res

}
execsql { PRAGMA count_changes = 0 }
drop_all_tables




do_test fkey2-1.4.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
  execsql { PRAGMA count_changes = 1 }
} {}
foreach {tn zSql res} $FkeySimpleTests {
  if {$res == "0 {}"} { set res {0 1} }
  execsql BEGIN
  do_test fkey2-1.4.$tn { catchsql $zSql } $res
  execsql COMMIT

}
execsql { PRAGMA count_changes = 0 }
drop_all_tables


# Special test: When the parent key is an IPK, make sure the affinity of
# the IPK is not applied to the child key value before it is inserted
# into the child table.
do_test fkey2-1.5.1 {
  execsql {
    CREATE TABLE i(i INTEGER PRIMARY KEY);
................................................................................
} {35.0 text 35 integer}
do_test fkey2-1.6.2 {
  catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}}

# Use a collation sequence on the parent key.
drop_all_tables

do_test fkey2-1.7.1 {
  execsql {
    CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
    CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
    INSERT INTO i VALUES('SQLite');
    INSERT INTO j VALUES('sqlite');
  }
................................................................................
    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
  );
}

fkey2-2-test 1  0 "INSERT INTO node VALUES(1, 0)"       FKV
fkey2-2-test 2  0 "BEGIN"
fkey2-2-test 3  1   "INSERT INTO node VALUES(1, 0)"

fkey2-2-test 4  0   "UPDATE node SET parent = NULL"
fkey2-2-test 5  0 "COMMIT"
fkey2-2-test 6  0 "SELECT * FROM node" {1 {}}

fkey2-2-test 7  0 "BEGIN"
fkey2-2-test 8  1   "INSERT INTO leaf VALUES('a', 2)"
fkey2-2-test 9  1   "INSERT INTO node VALUES(2, 0)"







<
<







 







<






>
>








>
>








>
>
>


<


<
>

>

<


>
>
>


<


<
<
|
<
>

<

>







 







>







 







>







22
23
24
25
26
27
28


29
30
31
32
33
34
35
...
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
...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
}

#-------------------------------------------------------------------------
# Test structure:
#
# fkey2-1.*: Simple tests to check that immediate and deferred foreign key 
#            constraints work when not inside a transaction.


#            explicit transactions (i.e that processing really is deferred).
#
# fkey2-3.*: Tests that a statement transaction is rolled back if an
#            immediate foreign key constraint is violated.
#
# fkey2-4.*: Test that FK actions may recurse even when recursive triggers
#            are disabled.
................................................................................
  4.9  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}
  4.10 "UPDATE t8 SET c=NULL WHERE d=4"   {0 {}}
  4.11 "DELETE FROM t7 WHERE b=1"         {1 {foreign key constraint failed}}
  4.12 "UPDATE t7 SET b = 2"              {1 {foreign key constraint failed}}
  4.13 "UPDATE t7 SET b = 1"              {0 {}}
  4.14 "INSERT INTO t8 VALUES('a', 'b')"  {1 {foreign key constraint failed}}
  4.15 "UPDATE t7 SET b = 5"              {1 {foreign key constraint failed}}

  4.17 "UPDATE t7 SET a = 10"             {0 {}}

  5.1  "INSERT INTO t9 VALUES(1, 3)"      {1 {no such table: main.nosuchtable}}
  5.2  "INSERT INTO t10 VALUES(1, 3)"     {1 {foreign key mismatch}}
}

# Run the simple tests with all FK constraints immediate.
#
do_test fkey2-1.1.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
} {}
foreach {tn zSql res} $FkeySimpleTests {
  do_test fkey2-1.1.$tn { catchsql $zSql } $res
}
drop_all_tables

# Run the simple tests with all FK constraints deferred.
#
do_test fkey2-1.2.0 {
  execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
} {}
foreach {tn zSql res} $FkeySimpleTests {
  do_test fkey2-1.2.$tn { catchsql $zSql } $res
}
drop_all_tables

# Run the simple tests with all FK constraints immediate. Put a 
# BEGIN/COMMIT block around each write to the database.
#
do_test fkey2-1.3.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]

} {}
foreach {tn zSql res} $FkeySimpleTests {

  execsql BEGIN
  do_test fkey2-1.3.$tn { catchsql $zSql } $res
  execsql COMMIT
}

drop_all_tables

# Run the simple tests with all FK constraints deferred. Put a 
# BEGIN/COMMIT block around each write to the database.
#
do_test fkey2-1.4.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]

} {}
foreach {tn zSql res} $FkeySimpleTests {


  do_test fkey2-1.4.$tn { catchsql "BEGIN; $zSql; COMMIT;" } $res

  catchsql commit
}

drop_all_tables


# Special test: When the parent key is an IPK, make sure the affinity of
# the IPK is not applied to the child key value before it is inserted
# into the child table.
do_test fkey2-1.5.1 {
  execsql {
    CREATE TABLE i(i INTEGER PRIMARY KEY);
................................................................................
} {35.0 text 35 integer}
do_test fkey2-1.6.2 {
  catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}}

# Use a collation sequence on the parent key.
drop_all_tables
puts "src4: the following requires collation support"
do_test fkey2-1.7.1 {
  execsql {
    CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
    CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
    INSERT INTO i VALUES('SQLite');
    INSERT INTO j VALUES('sqlite');
  }
................................................................................
    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
  );
}

fkey2-2-test 1  0 "INSERT INTO node VALUES(1, 0)"       FKV
fkey2-2-test 2  0 "BEGIN"
fkey2-2-test 3  1   "INSERT INTO node VALUES(1, 0)"

fkey2-2-test 4  0   "UPDATE node SET parent = NULL"
fkey2-2-test 5  0 "COMMIT"
fkey2-2-test 6  0 "SELECT * FROM node" {1 {}}

fkey2-2-test 7  0 "BEGIN"
fkey2-2-test 8  1   "INSERT INTO leaf VALUES('a', 2)"
fkey2-2-test 9  1   "INSERT INTO node VALUES(2, 0)"

Changes to test/permutations.test.

120
121
122
123
124
125
126

127
128
129
130
131






132
133
134
135
136
137
138
#############################################################################
# Start of tests
#

#-------------------------------------------------------------------------
# Define the generic test suites:
#

#   veryquick
#   quick
#   full
#
lappend ::testsuitelist xxx







test_suite "veryquick" -prefix "" -description {
  "Very" quick test suite. Runs in less than 5 minutes on a workstation. 
  This test suite is the same as the "quick" tests, except that some files
  that test malloc and IO errors are omitted.
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault*







>





>
>
>
>
>
>







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
#############################################################################
# Start of tests
#

#-------------------------------------------------------------------------
# Define the generic test suites:
#
#   src4
#   veryquick
#   quick
#   full
#
lappend ::testsuitelist xxx

test_suite "src4" -prefix "" -description {
} -files {
  simple.test fkey1.test conflict.test trigger2.test select1.test
  where.test
}

test_suite "veryquick" -prefix "" -description {
  "Very" quick test suite. Runs in less than 5 minutes on a workstation. 
  This test suite is the same as the "quick" tests, except that some files
  that test malloc and IO errors are omitted.
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault*

Changes to test/select1.test.

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
...
406
407
408
409
410
411
412

413
414
415
416
417
418
419
...
606
607
608
609
610
611
612

613
614
615
616
617
618
619
....
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
      GROUP BY f1
     HAVING max(m+5)<10
  }
} {1 {misuse of aliased aggregate m}}
do_test select1-2.23 {
  execsql {
    CREATE TABLE tkt2526(a,b,c PRIMARY KEY);
    INSERT INTO tkt2526 VALUES('x','y',NULL);
    INSERT INTO tkt2526 VALUES('x','z',NULL);
  }
  catchsql {
    SELECT count(a) AS cn FROM tkt2526 GROUP BY a HAVING cn<max(cn)
  }
} {1 {misuse of aliased aggregate cn}}

# WHERE clause expressions
................................................................................
} {0 33}

execsql {CREATE TABLE test2(t1 text, t2 text)}
execsql {INSERT INTO test2 VALUES('abc','xyz')}

# Check for column naming
#

do_test select1-6.1 {
  set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
  lappend v $msg
} {0 {f1 11 f1 33}}
do_test select1-6.1.1 {
  db eval {PRAGMA full_column_names=on}
  set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
................................................................................
} {test1.f1 11 test2.t1 abc}


db eval {
  PRAGMA short_column_names=ON;
  PRAGMA full_column_names=OFF;
}


ifcapable compound {
do_test select1-6.10 {
  set v [catch {execsql2 {
    SELECT f1 FROM test1 UNION SELECT f2 FROM test1
    ORDER BY f2;
  }} msg]
................................................................................
    SELECT * FROM sqlite_master WHERE rowid=10;
    SELECT * FROM sqlite_master WHERE rowid<10;
    SELECT * FROM sqlite_master WHERE rowid<=10;
    SELECT * FROM sqlite_master WHERE rowid>=10;
    SELECT * FROM sqlite_master;
  }
} {}

do_test select1-14.2 {
  execsql { 
    SELECT 10 IN (SELECT rowid FROM sqlite_master);
  }
} {0}

if {[db one {PRAGMA locking_mode}]=="normal"} {







|
|







 







>







 







>







 







>







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
....
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
      GROUP BY f1
     HAVING max(m+5)<10
  }
} {1 {misuse of aliased aggregate m}}
do_test select1-2.23 {
  execsql {
    CREATE TABLE tkt2526(a,b,c PRIMARY KEY);
    INSERT INTO tkt2526 VALUES('x','y',1);
    INSERT INTO tkt2526 VALUES('x','z',2);
  }
  catchsql {
    SELECT count(a) AS cn FROM tkt2526 GROUP BY a HAVING cn<max(cn)
  }
} {1 {misuse of aliased aggregate cn}}

# WHERE clause expressions
................................................................................
} {0 33}

execsql {CREATE TABLE test2(t1 text, t2 text)}
execsql {INSERT INTO test2 VALUES('abc','xyz')}

# Check for column naming
#
if 0 {
do_test select1-6.1 {
  set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
  lappend v $msg
} {0 {f1 11 f1 33}}
do_test select1-6.1.1 {
  db eval {PRAGMA full_column_names=on}
  set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
................................................................................
} {test1.f1 11 test2.t1 abc}


db eval {
  PRAGMA short_column_names=ON;
  PRAGMA full_column_names=OFF;
}
} ;# if 0 ...

ifcapable compound {
do_test select1-6.10 {
  set v [catch {execsql2 {
    SELECT f1 FROM test1 UNION SELECT f2 FROM test1
    ORDER BY f2;
  }} msg]
................................................................................
    SELECT * FROM sqlite_master WHERE rowid=10;
    SELECT * FROM sqlite_master WHERE rowid<10;
    SELECT * FROM sqlite_master WHERE rowid<=10;
    SELECT * FROM sqlite_master WHERE rowid>=10;
    SELECT * FROM sqlite_master;
  }
} {}

do_test select1-14.2 {
  execsql { 
    SELECT 10 IN (SELECT rowid FROM sqlite_master);
  }
} {0}

if {[db one {PRAGMA locking_mode}]=="normal"} {

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
299
300
301
302
303
304
305
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
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
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
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
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
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
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
# 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 {} 1 {} 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);
}

do_execsql_test 10.3 { UPDATE t1 SET b = 10 WHERE a=3 }
do_execsql_test 10.4 { SELECT * FROM t1 } {1 2 3 10}
do_execsql_test 10.5 { PRAGMA integrity_check } {ok}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 11.1 {
  CREATE TABLE t1(a, b, c, UNIQUE(a));
  INSERT INTO t1 VALUES(1,2,3);
}
do_catchsql_test 11.2 { 
  INSERT INTO t1 VALUES(1,2,4)
} {1 {column a is not unique}}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 12.1 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(3, 'three');
  INSERT INTO t1 VALUES(1, 'one');
  INSERT INTO t1 VALUES(2, 'two');
}
do_execsql_test 12.2 { SELECT * FROM t1 ORDER BY a } {1 one 2 two 3 three}
do_execsql_test 12.3 { SELECT * FROM t1 ORDER BY b } {1 one 3 three 2 two}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 13.1 {
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(3, 'three');
  INSERT INTO t1 VALUES(1, 'one');
  INSERT INTO t1 VALUES(2, 'two');
}
do_execsql_test 13.2  { SELECT a FROM t1 } {3 1 2}
do_execsql_test 13.3  { CREATE TABLE t2(x, y) }
do_execsql_test 13.4  { SELECT a FROM t1 } {3 1 2}
do_execsql_test 13.5  { DROP TABLE t2 }
do_execsql_test 13.6  { SELECT a FROM t1 } {3 1 2}
do_execsql_test 13.7  { CREATE TABLE t2 AS SELECT * FROM t1 }
do_execsql_test 13.8  { SELECT a FROM t2 } {3 1 2}
do_execsql_test 13.9  { DROP TABLE t1 }
do_execsql_test 13.10 { SELECT a FROM t2 } {3 1 2}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 14.1 {
  CREATE TABLE t1(a,b,c NOT NULL  DEFAULT 5);
  CREATE TABLE t2(a,b,c); 
  CREATE TABLE t3(x);

  INSERT INTO t2 VALUES(1,2,1);
  INSERT INTO t2 VALUES(2,3,2);
  INSERT INTO t2 VALUES(3,4,1);
  INSERT INTO t2 VALUES(4,5,4);

  INSERT INTO t3 VALUES(1);
}

do_execsql_test 14.2 { DROP TABLE t1 }
do_execsql_test 14.3 { SELECT * FROM t3 } 1

#-------------------------------------------------------------------------
reset_db

do_execsql_test 15.1.1 { CREATE TABLE t1(x PRIMARY KEY) }
do_execsql_test 15.1.2 { 
  BEGIN;
    INSERT INTO t1 VALUES('rollback is not implemented yet');
}
do_execsql_test 15.1.3 { ROLLBACK }
do_execsql_test 15.1.4 { SELECT * FROM t1 } {}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 16.1.1 {
  PRAGMA foreign_keys = ON;
  CREATE TABLE p1(x PRIMARY KEY);
  CREATE TABLE c1(y REFERENCES p1);

  INSERT INTO p1 VALUES(2);
  INSERT INTO p1 VALUES(4);
  INSERT INTO p1 VALUES(6);
}

do_execsql_test  16.1.2 { INSERT INTO c1 VALUES(2) }
do_catchsql_test 16.1.3 { 
  INSERT INTO c1 VALUES(3) 
} {1 {foreign key constraint failed}}
do_execsql_test 16.1.4 { SELECT * FROM c1 } {2}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 17.1 {

  PRAGMA foreign_keys = ON;
  CREATE TABLE t1(x PRIMARY KEY);
  CREATE TABLE t2(a PRIMARY KEY, b);

  INSERT INTO t1 VALUES('X');

  INSERT INTO t2 VALUES(1, 'A');
  INSERT INTO t2 VALUES(2, 'B');
  INSERT INTO t2 VALUES(3, 'C');
  INSERT INTO t2 VALUES(4, 'D');
  INSERT INTO t2 VALUES(5, 'A');
}

do_catchsql_test 17.2 { 
  INSERT INTO t1 SELECT b FROM t2;
} {1 {column x is not unique}}

do_execsql_test 17.3 { SELECT * FROM t1 } {X}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 18.1 {
  CREATE TABLE t1(a, b, c, UNIQUE(a,b) ON CONFLICT IGNORE);
  CREATE TABLE t2(x);

  INSERT INTO t1 VALUES(1,2,3);
  BEGIN;
    INSERT INTO t2 VALUES(1); 
    INSERT INTO t1 VALUES(1,2,4);
  COMMIT;
}

do_execsql_test 18.2 { SELECT * FROM t1 } {1 2 3}
do_execsql_test 18.3 { SELECT * FROM t2 } {1}

#-------------------------------------------------------------------------
reset_db

do_test 19.1 {
  catchsql {
    CREATE TABLE t4(x);
    CREATE UNIQUE INDEX t4x ON t4(x);
    BEGIN;
    INSERT INTO t4 VALUES(1);
    INSERT OR ROLLBACK INTO t4 VALUES(1);
  }
  execsql { SELECT * FROM t4 }
} {}

# Check the above closed the transaction.
do_execsql_test 19.2 { BEGIN }
do_execsql_test 19.3 { COMMIT }

#-------------------------------------------------------------------------
reset_db

do_execsql_test 20.1 {
  CREATE TABLE def(d, e, f);
  BEGIN;
  INSERT INTO def VALUES('a', 'b', 'c');

  INSERT INTO def SELECT * FROM def;
  INSERT INTO def SELECT * FROM def;
  INSERT INTO def SELECT * FROM def;
  INSERT INTO def SELECT * FROM def;
  INSERT INTO def SELECT * FROM def;

  SELECT count(*) FROM def;
} {32}

do_execsql_test 20.2 { ROLLBACK }
do_execsql_test 20.3 { SELECT count(*) FROM def } 0

#-------------------------------------------------------------------------
reset_db

do_execsql_test 21.1 {
  PRAGMA foreign_keys = on;
  CREATE TABLE t1(a PRIMARY KEY, b);
  CREATE TABLE t2(c REFERENCES t1(a), d);
}

do_execsql_test 21.2 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t2 VALUES(1, 3);
  INSERT INTO t2 VALUES(NULL, 4);
}

do_catchsql_test 21.3 {
  UPDATE t2 SET c=2 WHERE d=4;
} {1 {foreign key constraint failed}}


#-------------------------------------------------------------------------
reset_db

do_execsql_test 22.1 {
  CREATE TABLE t1(x PRIMARY KEY);
  INSERT INTO t1 VALUES('abc');
}

do_execsql_test 22.2 { UPDATE t1 SET x = 'abc' }
do_execsql_test 22.3 { SELECT * FROM t1 } {abc}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 23.1 {
  PRAGMA foreign_keys = on;
  CREATE TABLE t1(a PRIMARY KEY, b);
  CREATE TABLE t2(c REFERENCES t1(a), d);
}
proc out {} {
  set t1 [execsql {SELECT a FROM t1}]
  set t2 [execsql {SELECT c FROM t2}]
  puts "t1: $t1       t2: $t2"
}

do_test 23.2 {
  catchsql "BEGIN; INSERT INTO t2 VALUES(1, 3)" ; execsql COMMIT
} {}
do_test 23.3 {
  catchsql "BEGIN; INSERT INTO t1 VALUES(1, 2)" ; execsql COMMIT
} {}
do_test 23.4 {
  catchsql "BEGIN; INSERT INTO t2 VALUES(1, 3)" ; execsql COMMIT
} {}
do_test 23.5 {
  catchsql "BEGIN; INSERT INTO t2 VALUES(2, 4)" ; execsql COMMIT
} {}
do_test 23.6 {
  catchsql "BEGIN; INSERT INTO t2 VALUES(NULL, 4)" ; execsql COMMIT
} {}
do_test 23.7 {
  catchsql "BEGIN; UPDATE t2 SET c=2 WHERE d=4" ; execsql COMMIT
} {}
do_test 23.8 {
  catchsql "BEGIN; UPDATE t2 SET c=1 WHERE d=4" ; execsql COMMIT
} {}
do_test 23.9 {
  catchsql "BEGIN; UPDATE t2 SET c=1 WHERE d=4" ; execsql COMMIT
} {}
do_test 23.10 {
  catchsql "BEGIN; UPDATE t2 SET c=NULL WHERE d=4" ; execsql COMMIT
} {}
do_test 23.11 {
  execsql BEGIN
  catchsql "DELETE FROM t1 WHERE a=1"
  execsql COMMIT
} {}

do_catchsql_test 23.3 {
  BEGIN;
    UPDATE t1 SET a = 2;
  COMMIT;
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 24.1 {
  CREATE TABLE p(x INTEGER);
  INSERT INTO p VALUES(35.0);
  SELECT typeof(x) FROM p;
} {integer}

do_execsql_test 24.2 {
  CREATE TABLE p2(x INTEGER PRIMARY KEY);
  INSERT INTO p2 VALUES(35.0);
  SELECT typeof(x) FROM p2;
} {integer}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 25.1 {
  PRAGMA foreign_keys = on;
  CREATE TABLE p(x INT PRIMARY KEY);
  CREATE TABLE c(y REFERENCES p);
  INSERT INTO p VALUES(35);
  INSERT INTO c VALUES(35.0);
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 26.1 {
  PRAGMA foreign_keys = on;
  CREATE TABLE p(x INT PRIMARY KEY);
  CREATE TABLE c(y REFERENCES p);
  INSERT INTO p VALUES(35.0);
  INSERT INTO c VALUES(35.0);
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 27.1 {
  CREATE TABLE t1(a, b);
  CREATE TABLE log(x);
  CREATE TRIGGER BEFORE UPDATE ON t1 BEGIN
    INSERT INTO log VALUES(old.b || ' -> ' || new.b);
  END;
  INSERT INTO t1 VALUES(1, 'abc');
  UPDATE t1 SET b = 'xyz';
}
do_execsql_test 27.2 { SELECT * FROM log } {{abc -> xyz}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 28.1 {
  CREATE TABLE t1(a, b);
  CREATE TABLE log(x);
  CREATE TRIGGER BEFORE UPDATE ON t1 BEGIN
    INSERT INTO log VALUES('rowid=' || old.rowid);
  END;
  INSERT INTO t1 VALUES(1, 'abc');
}

do_execsql_test 28.2 { SELECT rowid FROM t1 } 1
do_execsql_test 28.3 { UPDATE t1 SET b = 'xyz'; }
do_execsql_test 28.4 { SELECT * FROM log } {{rowid=1}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 29.1 {
  CREATE TABLE t1(a, b);
  CREATE TABLE log(x,y,z);
  CREATE TRIGGER tr BEFORE INSERT ON t1 BEGIN
    INSERT INTO log VALUES(new.rowid, new.a, new.b);
  END;
}
do_execsql_test 29.2 { INSERT INTO t1 VALUES('one', 'abc') }
do_execsql_test 29.3 { SELECT * FROM log } {-1 one abc}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 30.1 {
  CREATE TABLE t1(a, b);
  CREATE TABLE log(x,y,z);
  CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN
    INSERT INTO log VALUES(new.rowid, new.a, new.b);
  END;
}
do_execsql_test 30.2 { INSERT INTO t1 VALUES('one', 'abc') }
do_execsql_test 30.3 { SELECT * FROM log } {1 one abc}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 31.1 {
  CREATE TABLE tbl(a PRIMARY KEY, b, c);
  CREATE TRIGGER tr AFTER INSERT ON tbl BEGIN
    UPDATE tbl SET b = '';
  END;
  INSERT INTO tbl VALUES(1, 2, 3);
}

do_execsql_test 31.2 { SELECT * FROM tbl } {1 {} 3}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 32.1 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(1, 2, 3);
}
do_execsql_test 32.2 { SELECT a, b, c FROM t1 } {1 2 3}
do_execsql_test 32.3 {
  DROP TABLE t1;
  CREATE TABLE t1(c, b, a);
  INSERT INTO t1 VALUES(1, 2, 3);
}
do_execsql_test 32.4 { SELECT a, b, c FROM t1 } {3 2 1}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 33.1 { CREATE TABLE t1(a, b, c) }
do_execsql_test 33.2 { CREATE TABLE t2(a, b, c) }
do_execsql_test 33.3 { CREATE TABLE t3(a, b, c) }
do_execsql_test 33.4 { CREATE TABLE t4(a, b, c) }

#-------------------------------------------------------------------------
reset_db
do_execsql_test 34.1 { CREATE TABLE t1(x PRIMARY KEY) }

do_execsql_test 34.2 { INSERT INTO t1 VALUES('123') }
do_test 34.3 { db changes } 1

do_execsql_test 34.4 { UPDATE t1 SET x = '456' }
do_test 34.5 { db changes } 1

do_execsql_test 34.6 { UPDATE t1 SET x = '456' WHERE x = '123' }
do_test 34.7 { db changes } 0

#-------------------------------------------------------------------------
reset_db
do_execsql_test 35.1 {
  CREATE TABLE tbl (a primary key, b, c);
  INSERT INTO tbl VALUES(1, 2, 3);
  INSERT INTO tbl VALUES(2, 2, 3);
  CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
    INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
  END;
}

do_execsql_test 35.2 { INSERT OR REPLACE INTO tbl values (2, 2, 3) }
do_execsql_test 35.3 { SELECT * from tbl } {1 2 3 2 0 0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 36.1 {
  CREATE TABLE tbl (a primary key, b, c);
  CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN
    UPDATE OR IGNORE tbl SET a = new.a, c = 10;
  END;

  BEGIN;
  INSERT INTO tbl VALUES(1, 3, 10);
  INSERT INTO tbl VALUES(2, 3, 4);
}
do_catchsql_test 36.2 {
  UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1;
} {1 {column a is not unique}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 37.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES('x', 'xxx');
  INSERT INTO t1 VALUES('y', 'yyy');
}
do_execsql_test 37.2 {
  BEGIN;
    DELETE FROM t1 WHERE a='y';
    INSERT INTO t1 VALUES('y', 'yyy');
    DELETE FROM t1 WHERE a='y';
    INSERT INTO t1 VALUES('y', 'yyy');
  ROLLBACK;
}
 
#-------------------------------------------------------------------------
reset_db
do_execsql_test 38.1 {
  CREATE TABLE t1(a, b);
  CREATE TABLE log(a, b);

  -- INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);

  CREATE VIEW v1 AS SELECT a, b FROM t1;
  CREATE TRIGGER tr1 INSTEAD OF DELETE ON v1 BEGIN
    INSERT INTO log VALUES(old.b, old.a);
  END;
}
do_execsql_test 38.2 {
  DELETE FROM v1 WHERE a = 3;
  SELECT * FROM log;
} {4 3}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 39.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
}
do_catchsql_test 39.2 {
  INSERT INTO t1 VALUES(NULL, 'xyz');
} {1 {t1.a may not be NULL}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 40.1 {
    CREATE TABLE abc(a, b, c, PRIMARY KEY(a, b));
    INSERT INTO abc VALUES(1, 1, 1);
    SELECT * FROM abc;
} {1 1 1}
do_execsql_test 40.2 { SELECT max(a) FROM abc } {1}
do_execsql_test 40.3 {
  SELECT a+(select max(a) FROM abc), 
         b+(select max(a) FROM abc), 
         c+(select max(a) FROM abc) 
  FROM abc
} {2 2 2}
do_execsql_test 40.4 {
  INSERT INTO abc SELECT 
      a+(select max(a) FROM abc), 
      b+(select max(a) FROM abc), 
      c+(select max(a) FROM abc) 
  FROM abc;
}
do_execsql_test 40.5 { SELECT * FROM abc } {1 1 1 2 2 2}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.1 {
  CREATE TABLE x(a, b);
  INSERT INTO x VALUES(1, 'one');
  INSERT INTO x VALUES(2, 'two');
  INSERT INTO x VALUES(1, 'three');
} 

do_execsql_test 41.2 {
  SELECT * FROM x ORDER BY a;
} {1 one 1 three 2 two}

#-------------------------------------------------------------------------
reset_db

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 42.$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 42.$t.$u $sql $res
  }
}

finish_test

Added test/src4.test.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
#    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.
#
#***********************************************************************
# This file runs all the tests run by quick.test except for those related
# to malloc or IO error simulation. With these tests omitted, the overall
# run time is reduced by about 75%.
#
# $Id: veryquick.test,v 1.9 2008/07/12 14:52:21 drh Exp $

set testdir [file dirname $argv0]
source $testdir/permutations.test

run_test_suite src4

finish_test

Changes to test/storage1.test.

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  lappend res [storage_prev $c1]
  lappend res [storage_key $c1]
  lappend res [storage_data $c1]
  lappend res [storage_prev $c1]
  storage_close_cursor $c1
  storage_close $x
  set res
} {SQLITE_INEXACT 014557 EF01 SQLITE_OK 012345 ABCD SQLITE_DONE}
do_test storage1-1.6 {
  set x [storage_open :memory:]
  storage_begin $x 2
  storage_replace $x 012345 abcd
  storage_replace $x 014567 ef01
  storage_replace $x 013456 deaf
  storage_replace $x 012345 eeaa







|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  lappend res [storage_prev $c1]
  lappend res [storage_key $c1]
  lappend res [storage_data $c1]
  lappend res [storage_prev $c1]
  storage_close_cursor $c1
  storage_close $x
  set res
} {SQLITE_INEXACT 014557 EF01 SQLITE_OK 012345 ABCD SQLITE_NOTFOUND}
do_test storage1-1.6 {
  set x [storage_open :memory:]
  storage_begin $x 2
  storage_replace $x 012345 abcd
  storage_replace $x 014567 ef01
  storage_replace $x 013456 deaf
  storage_replace $x 012345 eeaa

Changes to test/tester.tcl.

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
352
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
#
................................................................................
  set argv $leftover

  # 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
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
# 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
#
................................................................................
  set argv $leftover

  # 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 
  kvwrap install
  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} {

Changes to test/trigger2.test.

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
...
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
...
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
...
325
326
327
328
329
330
331

332
333
334
335
336
337
338
...
509
510
511
512
513
514
515

516
517
518
519
520
521

522
523
524
525
526
527
528
...
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
        INSERT INTO clog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM clog), 
  	  old.a, old.b, 
  	  (SELECT coalesce(sum(a),0) FROM tbl),
          (SELECT coalesce(sum(b),0) FROM tbl), 
  	  new.a, new.b);
      END;
    }
  
    do_test trigger2-1.$ii.1 {
      set r {}
      foreach v [execsql { 
        UPDATE tbl SET a = a * 10, b = b * 10;
        SELECT * FROM rlog ORDER BY idx;
        SELECT * FROM clog ORDER BY idx;
      }] {
        lappend r [expr {int($v)}]
      }
      set r
    } [list 1 1 2  4  6 10 20 \
            2 1 2 13 24 10 20 \
  	    3 3 4 13 24 30 40 \
  	    4 3 4 40 60 30 40 \
            1 1 2 13 24 10 20 ]

  
    execsql {
      DELETE FROM rlog;
      DELETE FROM tbl;
      INSERT INTO tbl VALUES (100, 100);
      INSERT INTO tbl VALUES (300, 200);
      CREATE TRIGGER delete_before_row BEFORE DELETE ON tbl FOR EACH ROW
................................................................................
        INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
  	  old.a, old.b, 
  	  (SELECT coalesce(sum(a),0) FROM tbl),
          (SELECT coalesce(sum(b),0) FROM tbl), 
  	  0, 0);
      END;
    }
    do_test trigger2-1.$ii.2 {
      set r {}
      foreach v [execsql {
        DELETE FROM tbl;
        SELECT * FROM rlog;
      }] {
        lappend r [expr {int($v)}]
      }
      set r
    } [list 1 100 100 400 300 0 0 \
            2 100 100 300 200 0 0 \
            3 300 200 300 200 0 0 \
            4 300 200 0 0 0 0 ]

  
    execsql {
      DELETE FROM rlog;
      CREATE TRIGGER insert_before_row BEFORE INSERT ON tbl FOR EACH ROW
        BEGIN
        INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
  	  0, 0,
................................................................................
        BEGIN
        INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
  	  0, 0,
  	  (SELECT coalesce(sum(a),0) FROM tbl),
          (SELECT coalesce(sum(b),0) FROM tbl), 
  	  new.a, new.b);
      END;
    }
    do_test trigger2-1.$ii.3 {
      execsql {
  
        CREATE TABLE other_tbl(a, b);
        INSERT INTO other_tbl VALUES(1, 2);
        INSERT INTO other_tbl VALUES(3, 4);



        -- INSERT INTO tbl SELECT * FROM other_tbl;
        INSERT INTO tbl VALUES(5, 6);
        DROP TABLE other_tbl;
  
        SELECT * FROM rlog;
      }
    } [list 1 0 0 0 0 5 6 \
            2 0 0 5 6 5 6 ]
  


    integrity_check trigger2-1.$ii.4
  }
  catchsql {
    DROP TABLE rlog;
    DROP TABLE clog;
    DROP TABLE tbl;
    DROP TABLE other_tbl;
................................................................................

    execsql "DELETE FROM tbl; DELETE FROM log; $prep";
    execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\
             ON tbl BEGIN $tr_program_fixed END;"

    do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data
    execsql "DROP TRIGGER the_trigger;"


    integrity_check trigger2-2.$ii-integrity
  }
}
catchsql {
  DROP TABLE tbl;
  DROP TABLE log;
................................................................................
    }
  } {1 {column a is not unique}}
  do_test trigger2-6.1e {
    execsql {
      SELECT * from tbl;
    }
  } {1 2 3 2 2 3}

  do_test trigger2-6.1f {
    execsql {
      INSERT OR REPLACE INTO tbl values (2, 2, 3);
      SELECT * from tbl;
    }
  } {1 2 3 2 0 0}

  do_test trigger2-6.1g {
    catchsql {
      INSERT OR ROLLBACK INTO tbl values (3, 2, 3);
    }
  } {1 {column a is not unique}}
  do_test trigger2-6.1h {
    execsql {
................................................................................
  execsql {
  CREATE TABLE ab(a, b);
  CREATE TABLE cd(c, d);
  INSERT INTO ab VALUES (1, 2);
  INSERT INTO ab VALUES (0, 0);
  INSERT INTO cd VALUES (3, 4);

  CREATE TABLE tlog(ii INTEGER PRIMARY KEY, 
      olda, oldb, oldc, oldd, newa, newb, newc, newd);

  CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd;

  CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
  END;
  CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
  END;

  CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	old.a, old.b, old.c, old.d, 0, 0, 0, 0);
  END;
  CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	old.a, old.b, old.c, old.d, 0, 0, 0, 0);
  END;

  CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
  END;
   CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
   END;
  }
} {};

do_test trigger2-7.2 {
  execsql {
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;




    DELETE FROM abcd WHERE a = 1;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    SELECT * FROM tlog;




  }


} [ list 1 1 2 3 4 100 25 3 4 \
         2 1 2 3 4 100 25 3 4 \
	 3 1 2 3 4 0 0 0 0 \
	 4 1 2 3 4 0 0 0 0 \
	 5 0 0 0 0 10 20 30 40 \
	 6 0 0 0 0 10 20 30 40 ]


do_test trigger2-7.3 {
  execsql {
    DELETE FROM tlog;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    DELETE FROM abcd WHERE a = 1;
    SELECT * FROM tlog;
  }
} [ list \
   1 0 0 0 0 10 20 30 40 \
   2 0 0 0 0 10 20 30 40 \
   3 1 2 3 4 100 25 3 4 \
   4 1 2 3 4 100 25 3 4 \
   5 1 2 3 4 0 0 0 0 \
   6 1 2 3 4 0 0 0 0 \
]
do_test trigger2-7.4 {
  execsql {
    DELETE FROM tlog;
    DELETE FROM abcd WHERE a = 1;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    SELECT * FROM tlog;
  }
} [ list \
   1 1 2 3 4 0 0 0 0 \
   2 1 2 3 4 0 0 0 0 \
   3 0 0 0 0 10 20 30 40 \
   4 0 0 0 0 10 20 30 40 \
   5 1 2 3 4 100 25 3 4 \
   6 1 2 3 4 100 25 3 4 \
]

do_test trigger2-8.1 {
  execsql {
    CREATE TABLE t1(a,b,c);
    INSERT INTO t1 VALUES(1,2,3);
    CREATE VIEW v1 AS







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







 







|
<
<


<
<
|
<
|
|
|
|
>







 







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







 







>







 







>






>







 







<
|




|



|




|



|




|



|





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










|
|
|
|
|
|










|
|
|
|
|
|







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
...
154
155
156
157
158
159
160
161


162
163


164

165
166
167
168
169
170
171
172
173
174
175
176
...
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
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
...
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
        INSERT INTO clog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM clog), 
  	  old.a, old.b, 
  	  (SELECT coalesce(sum(a),0) FROM tbl),
          (SELECT coalesce(sum(b),0) FROM tbl), 
  	  new.a, new.b);
      END;
    }

    do_execsql_test trigger2-1.$ii.1 {


      UPDATE tbl SET a = a * 10, b = b * 10;
      SELECT * FROM rlog ORDER BY idx;
      SELECT * FROM clog ORDER BY idx;


    } {

      1 1 2  4  6 10 20
      2 1 2 13 24 10 20
      3 3 4 13 24 30 40
      4 3 4 40 60 30 40
      1 1 2 13 24 10 20
    }
  
    execsql {
      DELETE FROM rlog;
      DELETE FROM tbl;
      INSERT INTO tbl VALUES (100, 100);
      INSERT INTO tbl VALUES (300, 200);
      CREATE TRIGGER delete_before_row BEFORE DELETE ON tbl FOR EACH ROW
................................................................................
        INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
  	  old.a, old.b, 
  	  (SELECT coalesce(sum(a),0) FROM tbl),
          (SELECT coalesce(sum(b),0) FROM tbl), 
  	  0, 0);
      END;
    }
    do_execsql_test trigger2-1.$ii.2 {


        DELETE FROM tbl;
        SELECT * FROM rlog;


    } {

      1 100 100 400 300 0 0
      2 100 100 300 200 0 0
      3 300 200 300 200 0 0
      4 300 200 0 0 0 0 
    }
  
    execsql {
      DELETE FROM rlog;
      CREATE TRIGGER insert_before_row BEFORE INSERT ON tbl FOR EACH ROW
        BEGIN
        INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
  	  0, 0,
................................................................................
        BEGIN
        INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
  	  0, 0,
  	  (SELECT coalesce(sum(a),0) FROM tbl),
          (SELECT coalesce(sum(b),0) FROM tbl), 
  	  new.a, new.b);
      END;




      CREATE TABLE other_tbl(a, b);
      INSERT INTO other_tbl VALUES(1, 2);
      INSERT INTO other_tbl VALUES(3, 4);
    }

    do_execsql_test trigger2-1.$ii.3 {
      -- INSERT INTO tbl SELECT * FROM other_tbl;
      INSERT INTO tbl VALUES(5, 6);


      SELECT * FROM rlog;
    } {
      1 0 0 0 0 5 6
      2 0 0 5 6 5 6 
    }

    execsql { DROP TABLE other_tbl }
    integrity_check trigger2-1.$ii.4
  }
  catchsql {
    DROP TABLE rlog;
    DROP TABLE clog;
    DROP TABLE tbl;
    DROP TABLE other_tbl;
................................................................................

    execsql "DELETE FROM tbl; DELETE FROM log; $prep";
    execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\
             ON tbl BEGIN $tr_program_fixed END;"

    do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data
    execsql "DROP TRIGGER the_trigger;"


    integrity_check trigger2-2.$ii-integrity
  }
}
catchsql {
  DROP TABLE tbl;
  DROP TABLE log;
................................................................................
    }
  } {1 {column a is not unique}}
  do_test trigger2-6.1e {
    execsql {
      SELECT * from tbl;
    }
  } {1 2 3 2 2 3}

  do_test trigger2-6.1f {
    execsql {
      INSERT OR REPLACE INTO tbl values (2, 2, 3);
      SELECT * from tbl;
    }
  } {1 2 3 2 0 0}

  do_test trigger2-6.1g {
    catchsql {
      INSERT OR ROLLBACK INTO tbl values (3, 2, 3);
    }
  } {1 {column a is not unique}}
  do_test trigger2-6.1h {
    execsql {
................................................................................
  execsql {
  CREATE TABLE ab(a, b);
  CREATE TABLE cd(c, d);
  INSERT INTO ab VALUES (1, 2);
  INSERT INTO ab VALUES (0, 0);
  INSERT INTO cd VALUES (3, 4);


  CREATE TABLE tlog(olda, oldb, oldc, oldd, newa, newb, newc, newd);

  CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd;

  CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN
    INSERT INTO tlog VALUES(
	old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
  END;
  CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN
    INSERT INTO tlog VALUES(
	old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
  END;

  CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN
    INSERT INTO tlog VALUES(
	old.a, old.b, old.c, old.d, 0, 0, 0, 0);
  END;
  CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN
    INSERT INTO tlog VALUES(
	old.a, old.b, old.c, old.d, 0, 0, 0, 0);
  END;

  CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN
    INSERT INTO tlog VALUES(
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
  END;
   CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN
    INSERT INTO tlog VALUES(
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
   END;
  }
} {};



do_execsql_test trigger2-7.2.1 { UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1 }
do_execsql_test trigger2.7.2.2 { SELECT * FROM tlog } {
  1 2 3 4 100 25 3 4 
  1 2 3 4 100 25 3 4 
}
do_execsql_test trigger2-7.2.3 { DELETE FROM abcd WHERE a = 1 }

do_execsql_test trigger2.7.2.4 { SELECT * FROM tlog } {
  1 2 3 4 100 25 3 4 
  1 2 3 4 100 25 3 4 
  1 2 3 4 0 0 0 0 
  1 2 3 4 0 0 0 0
}
do_execsql_test trigger2-7.2.5 { INSERT INTO abcd VALUES(10, 20, 30, 40) }
do_execsql_test trigger2.7.2.6 { SELECT * FROM tlog } {
  1 2 3 4 100 25 3 4 
  1 2 3 4 100 25 3 4 
  1 2 3 4 0 0 0 0 
  1 2 3 4 0 0 0 0
  0 0 0 0 10 20 30 40 
  0 0 0 0 10 20 30 40 
}

do_test trigger2-7.3 {
  execsql {
    DELETE FROM tlog;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    DELETE FROM abcd WHERE a = 1;
    SELECT * FROM tlog;
  }
} [ list \
   0 0 0 0 10 20 30 40 \
   0 0 0 0 10 20 30 40 \
   1 2 3 4 100 25 3 4 \
   1 2 3 4 100 25 3 4 \
   1 2 3 4 0 0 0 0 \
   1 2 3 4 0 0 0 0 \
]
do_test trigger2-7.4 {
  execsql {
    DELETE FROM tlog;
    DELETE FROM abcd WHERE a = 1;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    SELECT * FROM tlog;
  }
} [ list \
   1 2 3 4 0 0 0 0 \
   1 2 3 4 0 0 0 0 \
   0 0 0 0 10 20 30 40 \
   0 0 0 0 10 20 30 40 \
   1 2 3 4 100 25 3 4 \
   1 2 3 4 100 25 3 4 \
]

do_test trigger2-8.1 {
  execsql {
    CREATE TABLE t1(a,b,c);
    INSERT INTO t1 VALUES(1,2,3);
    CREATE VIEW v1 AS

Changes to test/where.test.

49
50
51
52
53
54
55
56
57


58
59
60
61
62
63
64
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
...
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
...
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
...
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
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
...
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
...
554
555
556
557
558
559
560

561
562
563
564
565
566
567
568
569
570
571
...
618
619
620
621
622
623
624

625
626
627
628
629

630
631
632
633
634
635
636
....
1104
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
    CREATE INDEX i2qs ON t2(q, s);
  }
} {}

# Do an SQL statement.  Append the search count to the end of the result.
#
proc count sql {
  set ::sqlite_search_count 0
  return [concat [execsql $sql] $::sqlite_search_count]


}

# Verify that queries use an index.  We are using the special variable
# "sqlite_search_count" which tallys the number of executions of MoveTo
# and Next operators in the VDBE.  By verifing that the search count is
# small we can be assured that indices are being used properly.
#
................................................................................
} {3 144 3}
do_test where-1.8.2 {
  set sqlite_query_plan
} {t1 i1xy}
do_test where-1.8.3 {
  count {SELECT x, y FROM t1 WHERE y=144 AND x=3}
  set sqlite_query_plan
} {{} i1xy}
do_test where-1.9 {
  count {SELECT x, y FROM t1 WHERE y=144 AND w>10 AND x=3}
} {3 144 3}
do_test where-1.10 {
  count {SELECT x, y FROM t1 WHERE x=3 AND w>=10 AND y=121}
} {3 121 3}
do_test where-1.11 {
................................................................................
#
# do_test where-1.26 {
#   count {SELECT w FROM t1 WHERE x=3 AND y BETWEEN 121 AND 196}
# } {10 11 12 13 9}

do_test where-1.27 {
  count {SELECT w FROM t1 WHERE x=3 AND y+1==122}
} {10 10}

do_test where-1.28 {
  count {SELECT w FROM t1 WHERE x+1=4 AND y+1==122}
} {10 99}
do_test where-1.29 {
  count {SELECT w FROM t1 WHERE y==121}
} {10 99}


do_test where-1.30 {
  count {SELECT w FROM t1 WHERE w>97}
} {98 99 100 3}
do_test where-1.31 {
  count {SELECT w FROM t1 WHERE w>=97}
} {97 98 99 100 4}
do_test where-1.33 {
  count {SELECT w FROM t1 WHERE w==97}
} {97 2}
do_test where-1.33.1  {
  count {SELECT w FROM t1 WHERE w<=97 AND w==97}
} {97 2}
do_test where-1.33.2  {
  count {SELECT w FROM t1 WHERE w<98 AND w==97}
} {97 2}
do_test where-1.33.3  {
  count {SELECT w FROM t1 WHERE w>=97 AND w==97}
} {97 2}
do_test where-1.33.4  {
  count {SELECT w FROM t1 WHERE w>96 AND w==97}
} {97 2}
do_test where-1.33.5  {
  count {SELECT w FROM t1 WHERE w==97 AND w==97}
} {97 2}
do_test where-1.34 {
  count {SELECT w FROM t1 WHERE w+1==98}
} {97 99}
do_test where-1.35 {
  count {SELECT w FROM t1 WHERE w<3}
} {1 2 2}
do_test where-1.36 {
  count {SELECT w FROM t1 WHERE w<=3}
} {1 2 3 3}
do_test where-1.37 {
  count {SELECT w FROM t1 WHERE w+1<=4 ORDER BY w}
} {1 2 3 99}

do_test where-1.38 {
  count {SELECT (w) FROM t1 WHERE (w)>(97)}
} {98 99 100 3}
do_test where-1.39 {
  count {SELECT (w) FROM t1 WHERE (w)>=(97)}
} {97 98 99 100 4}
do_test where-1.40 {
  count {SELECT (w) FROM t1 WHERE (w)==(97)}
} {97 2}
do_test where-1.41 {
  count {SELECT (w) FROM t1 WHERE ((w)+(1))==(98)}
} {97 99}


# Do the same kind of thing except use a join as the data source.
#
do_test where-2.1 {
  count {
    SELECT w, p FROM t2, t1
................................................................................
# Lets do a 3-way join.
#
do_test where-3.1 {
  count {
    SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C
    WHERE C.w=101-B.p AND B.r=10202-A.y AND A.w=11
  }
} {11 90 11 8}
do_test where-3.2 {
  count {
    SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C
    WHERE C.w=101-B.p AND B.r=10202-A.y AND A.w=12
  }
} {12 89 12 8}
do_test where-3.3 {
  count {
    SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C
    WHERE A.w=15 AND B.p=C.w AND B.r=10202-A.y
  }
} {15 86 86 8}

# Test to see that the special case of a constant WHERE clause is
# handled.
#
do_test where-4.1 {
  count {
    SELECT * FROM t1 WHERE 0
  }
} {0}
do_test where-4.2 {
  count {
    SELECT * FROM t1 WHERE 1 LIMIT 1
  }
} {1 0 4 0}
do_test where-4.3 {
  execsql {
    SELECT 99 WHERE 0
  }
} {}
do_test where-4.4 {
  execsql {
................................................................................
# Omit these tests if the build is not capable of sub-queries.
#
ifcapable subquery {
  do_test where-5.1 {
    count {
      SELECT * FROM t1 WHERE rowid IN (1,2,3,1234) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 4}
  do_test where-5.2 {
    count {
      SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 102}
  do_test where-5.3 {
    count {
      SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 14}
  do_test where-5.4 {
    count {
      SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 102}
  do_test where-5.5 {
    count {
      SELECT * FROM t1 WHERE rowid IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 3}
  do_test where-5.6 {
    count {
      SELECT * FROM t1 WHERE rowid+0 IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 103}
  do_test where-5.7 {
    count {
      SELECT * FROM t1 WHERE w IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 9}
  do_test where-5.8 {
    count {
      SELECT * FROM t1 WHERE w+0 IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 103}
  do_test where-5.9 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1;
    }
  } {2 1 9 3 1 16 7}
  do_test where-5.10 {
    count {
      SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1;
    }
  } {2 1 9 3 1 16 199}
  do_test where-5.11 {
    count {
      SELECT * FROM t1 WHERE y IN (6400,8100) ORDER BY 1;
    }
  } {79 6 6400 89 6 8100 199}
  do_test where-5.12 {
    count {
      SELECT * FROM t1 WHERE x=6 AND y IN (6400,8100) ORDER BY 1;
    }
  } {79 6 6400 89 6 8100 7}
  do_test where-5.13 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1;
    }
  } {2 1 9 3 1 16 7}
  do_test where-5.14 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1;
    }
  } {2 1 9 8}
  do_test where-5.15 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1;
    }
  } {2 1 9 3 1 16 11}
}

# This procedure executes the SQL.  Then it checks to see if the OP_Sort
# opcode was executed.  If an OP_Sort did occur, then "sort" is appended
# to the result.  If no OP_Sort happened, then "nosort" is appended.
#
# This procedure is used to check to make sure sorting is or is not
................................................................................
  }
} {1 100 4 2 99 9 3 98 16 sort}
do_test where-6.4 {
  cksort {
    SELECT * FROM t3 WHERE a<10 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}

do_test where-6.5 {
  cksort {
    SELECT * FROM t3 WHERE a>0 AND a<10 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}
do_test where-6.6 {
  cksort {
    SELECT * FROM t3 WHERE a>0 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}

do_test where-6.7 {


  cksort {
    SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}

ifcapable subquery {
  do_test where-6.8 {
    cksort {
      SELECT * FROM t3 WHERE a IN (3,5,7,1,9,4,2) ORDER BY a LIMIT 3
    }
  } {1 100 4 2 99 9 3 98 16 sort}
}
................................................................................
} {1 100 4 nosort}
do_test where-6.9.6 {
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c DESC LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.7 {

  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c,a LIMIT 3
  }
} {1 100 4 sort}
do_test where-6.9.8 {
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a DESC, c ASC LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.9 {
  cksort {
................................................................................
  }
} {4 9 16 nosort}
do_test where-6.20 {
  cksort {
    SELECT y FROM t1 ORDER BY rowid LIMIT 3;
  }
} {4 9 16 nosort}

do_test where-6.21 {
  cksort {
    SELECT y FROM t1 ORDER BY rowid, y LIMIT 3;
  }
} {4 9 16 nosort}

do_test where-6.22 {
  cksort {
    SELECT y FROM t1 ORDER BY rowid, y DESC LIMIT 3;
  }
} {4 9 16 nosort}
do_test where-6.23 {
  cksort {
................................................................................
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b DESC
  } 
} {1/1 1/4 4/1 4/4 nosort}
do_test where-14.5 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b
  } 
} {4/1 4/4 1/1 1/4 nosort}
do_test where-14.6 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC
  } 
} {4/1 4/4 1/1 1/4 nosort}
do_test where-14.7 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b
  } 
} {4/1 4/4 1/1 1/4 sort}
do_test where-14.7.1 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a, y.a||y.b
  } 
} {4/1 4/4 1/1 1/4 sort}

do_test where-14.7.2 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a, x.a||x.b
  } 
} {4/1 4/4 1/1 1/4 nosort}

do_test where-14.8 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b DESC
  } 
} {4/4 4/1 1/4 1/1 sort}
do_test where-14.9 {
  cksort {







|
|
>
>







 







|







 







|



|


|




|


|


|


|


|


|


|


|


|


|


|


|



|


|


|


|







 







|





|





|













|







 







|




|




|




|






|






|






|






|




|




|




|




|




|




|




|







 







>










>

>
>



|
>







 







>



|







 







>





>







 







|




|










>





>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
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
...
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
...
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
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
...
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
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
....
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
    CREATE INDEX i2qs ON t2(q, s);
  }
} {}

# Do an SQL statement.  Append the search count to the end of the result.
#
proc count sql {
  kvwrap reset
  set res [execsql $sql]
  #puts "sql={$sql} seek=[kvwrap seek] step=[kvwrap step]"
  return [concat $res [expr [kvwrap step] + [kvwrap seek]]]
}

# Verify that queries use an index.  We are using the special variable
# "sqlite_search_count" which tallys the number of executions of MoveTo
# and Next operators in the VDBE.  By verifing that the search count is
# small we can be assured that indices are being used properly.
#
................................................................................
} {3 144 3}
do_test where-1.8.2 {
  set sqlite_query_plan
} {t1 i1xy}
do_test where-1.8.3 {
  count {SELECT x, y FROM t1 WHERE y=144 AND x=3}
  set sqlite_query_plan
} {t1 i1xy}
do_test where-1.9 {
  count {SELECT x, y FROM t1 WHERE y=144 AND w>10 AND x=3}
} {3 144 3}
do_test where-1.10 {
  count {SELECT x, y FROM t1 WHERE x=3 AND w>=10 AND y=121}
} {3 121 3}
do_test where-1.11 {
................................................................................
#
# do_test where-1.26 {
#   count {SELECT w FROM t1 WHERE x=3 AND y BETWEEN 121 AND 196}
# } {10 11 12 13 9}

do_test where-1.27 {
  count {SELECT w FROM t1 WHERE x=3 AND y+1==122}
} {10 17}

do_test where-1.28 {
  count {SELECT w FROM t1 WHERE x+1=4 AND y+1==122}
} {10 101}
do_test where-1.29 {
  count {SELECT w FROM t1 WHERE y==121}
} {10 101}


do_test where-1.30 {
  count {SELECT w FROM t1 WHERE w>97}
} {98 99 100 7}
do_test where-1.31 {
  count {SELECT w FROM t1 WHERE w>=97}
} {97 98 99 100 9}
do_test where-1.33 {
  count {SELECT w FROM t1 WHERE w==97}
} {97 3}
do_test where-1.33.1  {
  count {SELECT w FROM t1 WHERE w<=97 AND w==97}
} {97 3}
do_test where-1.33.2  {
  count {SELECT w FROM t1 WHERE w<98 AND w==97}
} {97 3}
do_test where-1.33.3  {
  count {SELECT w FROM t1 WHERE w>=97 AND w==97}
} {97 3}
do_test where-1.33.4  {
  count {SELECT w FROM t1 WHERE w>96 AND w==97}
} {97 3}
do_test where-1.33.5  {
  count {SELECT w FROM t1 WHERE w==97 AND w==97}
} {97 3}
do_test where-1.34 {
  count {SELECT w FROM t1 WHERE w+1==98}
} {97 101}
do_test where-1.35 {
  count {SELECT w FROM t1 WHERE w<3}
} {1 2 5}
do_test where-1.36 {
  count {SELECT w FROM t1 WHERE w<=3}
} {1 2 3 7}
do_test where-1.37 {
  count {SELECT w FROM t1 WHERE w+1<=4 ORDER BY w}
} {1 2 3 201}

do_test where-1.38 {
  count {SELECT (w) FROM t1 WHERE (w)>(97)}
} {98 99 100 7}
do_test where-1.39 {
  count {SELECT (w) FROM t1 WHERE (w)>=(97)}
} {97 98 99 100 9}
do_test where-1.40 {
  count {SELECT (w) FROM t1 WHERE (w)==(97)}
} {97 3}
do_test where-1.41 {
  count {SELECT (w) FROM t1 WHERE ((w)+(1))==(98)}
} {97 101}


# Do the same kind of thing except use a join as the data source.
#
do_test where-2.1 {
  count {
    SELECT w, p FROM t2, t1
................................................................................
# Lets do a 3-way join.
#
do_test where-3.1 {
  count {
    SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C
    WHERE C.w=101-B.p AND B.r=10202-A.y AND A.w=11
  }
} {11 90 11 9}
do_test where-3.2 {
  count {
    SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C
    WHERE C.w=101-B.p AND B.r=10202-A.y AND A.w=12
  }
} {12 89 12 9}
do_test where-3.3 {
  count {
    SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C
    WHERE A.w=15 AND B.p=C.w AND B.r=10202-A.y
  }
} {15 86 86 9}

# Test to see that the special case of a constant WHERE clause is
# handled.
#
do_test where-4.1 {
  count {
    SELECT * FROM t1 WHERE 0
  }
} {0}
do_test where-4.2 {
  count {
    SELECT * FROM t1 WHERE 1 LIMIT 1
  }
} {1 0 4 1}
do_test where-4.3 {
  execsql {
    SELECT 99 WHERE 0
  }
} {}
do_test where-4.4 {
  execsql {
................................................................................
# Omit these tests if the build is not capable of sub-queries.
#
ifcapable subquery {
  do_test where-5.1 {
    count {
      SELECT * FROM t1 WHERE rowid IN (1,2,3,1234) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 7}
  do_test where-5.2 {
    count {
      SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 201}
  do_test where-5.3 {
    count {
      SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 10}
  do_test where-5.4 {
    count {
      SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
    }
  } {1 0 4 2 1 9 3 1 16 201}
  do_test where-5.5 {
    count {
      SELECT * FROM t1 WHERE rowid IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 9}
  do_test where-5.6 {
    count {
      SELECT * FROM t1 WHERE rowid+0 IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 206}
  do_test where-5.7 {
    count {
      SELECT * FROM t1 WHERE w IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 11}
  do_test where-5.8 {
    count {
      SELECT * FROM t1 WHERE w+0 IN 
         (select rowid from t1 where rowid IN (-1,2,4))
      ORDER BY 1;
    }
  } {2 1 9 4 2 25 206}
  do_test where-5.9 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1;
    }
  } {2 1 9 3 1 16 6}
  do_test where-5.10 {
    count {
      SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1;
    }
  } {2 1 9 3 1 16 201}
  do_test where-5.11 {
    count {
      SELECT * FROM t1 WHERE y IN (6400,8100) ORDER BY 1;
    }
  } {79 6 6400 89 6 8100 201}
  do_test where-5.12 {
    count {
      SELECT * FROM t1 WHERE x=6 AND y IN (6400,8100) ORDER BY 1;
    }
  } {79 6 6400 89 6 8100 6}
  do_test where-5.13 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1;
    }
  } {2 1 9 3 1 16 6}
  do_test where-5.14 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1;
    }
  } {2 1 9 6}
  do_test where-5.15 {
    count {
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1;
    }
  } {2 1 9 3 1 16 8}
}

# This procedure executes the SQL.  Then it checks to see if the OP_Sort
# opcode was executed.  If an OP_Sort did occur, then "sort" is appended
# to the result.  If no OP_Sort happened, then "nosort" is appended.
#
# This procedure is used to check to make sure sorting is or is not
................................................................................
  }
} {1 100 4 2 99 9 3 98 16 sort}
do_test where-6.4 {
  cksort {
    SELECT * FROM t3 WHERE a<10 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}

do_test where-6.5 {
  cksort {
    SELECT * FROM t3 WHERE a>0 AND a<10 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}
do_test where-6.6 {
  cksort {
    SELECT * FROM t3 WHERE a>0 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}

do_test where-6.7 {
  # UPDATE: src4 does a sort here. It picks a different index because it
  # does not support the covering index optimization.
  cksort {
    SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 sort}

ifcapable subquery {
  do_test where-6.8 {
    cksort {
      SELECT * FROM t3 WHERE a IN (3,5,7,1,9,4,2) ORDER BY a LIMIT 3
    }
  } {1 100 4 2 99 9 3 98 16 sort}
}
................................................................................
} {1 100 4 nosort}
do_test where-6.9.6 {
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c DESC LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.7 {
  # UPDATE: src4 uses t3acb here. So does not require an external sort.
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c,a LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.8 {
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a DESC, c ASC LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.9 {
  cksort {
................................................................................
  }
} {4 9 16 nosort}
do_test where-6.20 {
  cksort {
    SELECT y FROM t1 ORDER BY rowid LIMIT 3;
  }
} {4 9 16 nosort}

do_test where-6.21 {
  cksort {
    SELECT y FROM t1 ORDER BY rowid, y LIMIT 3;
  }
} {4 9 16 nosort}

do_test where-6.22 {
  cksort {
    SELECT y FROM t1 ORDER BY rowid, y DESC LIMIT 3;
  }
} {4 9 16 nosort}
do_test where-6.23 {
  cksort {
................................................................................
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b DESC
  } 
} {1/1 1/4 4/1 4/4 nosort}
do_test where-14.5 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b
  } 
} {4/1 4/4 1/1 1/4 sort}
do_test where-14.6 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC
  } 
} {4/1 4/4 1/1 1/4 sort}
do_test where-14.7 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b
  } 
} {4/1 4/4 1/1 1/4 sort}
do_test where-14.7.1 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a, y.a||y.b
  } 
} {4/1 4/4 1/1 1/4 sort}

do_test where-14.7.2 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a, x.a||x.b
  } 
} {4/1 4/4 1/1 1/4 nosort}

do_test where-14.8 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b DESC
  } 
} {4/4 4/1 1/4 1/1 sort}
do_test where-14.9 {
  cksort {