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

Difference From c13692183a5ea052 To 8eb90b66474992a7

2013-07-30
20:27
Combine the OP_MakeIdxKey and OP_MakeKey opcodes into a single OP_MakeKey that does the work of both. Standardize the parameter meanings on OP_MakeRecord and OP_MakeKey. Remove the unused OP_Seek opcode. Other related code simplifications and cleanup. check-in: ed5d6992cd user: drh tags: trunk
20:01
Add experimental sqlite_kvstore table. Currently read-only. check-in: c13692183a user: dan tags: trunk
16:57
Remove an unnecessary function call in lsm_sorted.c slowing down xNext() operations. check-in: 48d0585fff user: dan tags: trunk
2013-06-25
14:47
Have the planner always consider the PK index, even when it does not serve to satisfy any contraints or ordering requirements. check-in: 95933bb7ca user: dan tags: trunk
11:58
Run test files analyze5.test, analyze6.test and analyze7.test as part of src4.test. check-in: 8eb90b6647 user: dan tags: trunk
2013-06-24
20:06
Fix another bug in sqlite_stat3 related code. check-in: bad9060b5b user: dan tags: trunk

Changes to main.mk.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
OPTS += -DHAVE_GMTIME_R
OPTS += -DHAVE_LOCALTIME_R
OPTS += -DHAVE_MALLOC_USABLE_SIZE
OPTS += -DHAVE_USLEEP
#OPTS += -DSQLITE4_MEMDEBUG=1
#OPTS += -DSQLITE4_NO_SYNC=1 -DLSM_NO_SYNC=1
#OPTS += -DSQLITE4_OMIT_ANALYZE
#OPTS += -DSQLITE4_OMIT_AUTOMATIC_INDEX
OPTS += -DSQLITE4_OMIT_VIRTUALTABLE=1
OPTS += -DSQLITE4_OMIT_XFER_OPT
OPTS += -DSQLITE4_THREADSAFE=0

# This is how we compile
#
TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 







|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
OPTS += -DHAVE_GMTIME_R
OPTS += -DHAVE_LOCALTIME_R
OPTS += -DHAVE_MALLOC_USABLE_SIZE
OPTS += -DHAVE_USLEEP
#OPTS += -DSQLITE4_MEMDEBUG=1
#OPTS += -DSQLITE4_NO_SYNC=1 -DLSM_NO_SYNC=1
#OPTS += -DSQLITE4_OMIT_ANALYZE
OPTS += -DSQLITE4_OMIT_AUTOMATIC_INDEX
OPTS += -DSQLITE4_OMIT_VIRTUALTABLE=1
OPTS += -DSQLITE4_OMIT_XFER_OPT
OPTS += -DSQLITE4_THREADSAFE=0

# This is how we compile
#
TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 
Changes to src/alter.c.
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
          "sql = CASE "
            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
            "ELSE sqlite_rename_table(sql, %Q) END, "
#endif
          "tbl_name = %Q, "
          "name = CASE "
            "WHEN type='table' THEN %Q "
            "WHEN name LIKE 'sqlite_%%_unique%%' AND type='index' THEN "
             "'sqlite_' || %Q || substr(name,%d+8) "
            "ELSE name END "
      "WHERE tbl_name=%Q AND "
          "(type='table' OR type='index' OR type='trigger');", 
      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
#ifndef SQLITE4_OMIT_TRIGGER
      zName,
#endif







|
|







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
          "sql = CASE "
            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
            "ELSE sqlite_rename_table(sql, %Q) END, "
#endif
          "tbl_name = %Q, "
          "name = CASE "
            "WHEN type='table' THEN %Q "
            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
             "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
            "ELSE name END "
      "WHERE tbl_name=%Q AND "
          "(type='table' OR type='index' OR type='trigger');", 
      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
#ifndef SQLITE4_OMIT_TRIGGER
      zName,
#endif
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
    pDflt = 0;
  }

  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
  ** If there is a NOT NULL constraint, then the default value for the
  ** column must not be NULL.
  */
  if( pCol->iPrimKey>0 ){
    sqlite4ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
    return;
  }
  if( pNew->pIndex ){
    sqlite4ErrorMsg(pParse, "Cannot add a UNIQUE column");
    return;
  }







|







635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
    pDflt = 0;
  }

  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
  ** If there is a NOT NULL constraint, then the default value for the
  ** column must not be NULL.
  */
  if( pCol->isPrimKey ){
    sqlite4ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
    return;
  }
  if( pNew->pIndex ){
    sqlite4ErrorMsg(pParse, "Cannot add a UNIQUE column");
    return;
  }
Changes to src/analyze.c.
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
** column contains a single integer which is the (estimated) number of
** rows in the table identified by sqlite_stat1.tbl.
**
** Format for sqlite_stat3:
**
** The sqlite_stat3 table may contain multiple entries for each index.
** The idx column names the index and the tbl column contains the name
** of the indexed table. If the idx and tbl columns are the same, then the 
** sample is of the PRIMARY KEY index. The sample column is a value taken 
** from the left-most column of the index encoded using the key-encoding. 
** The nEq column is the approximate number of entires in the index whose 
** left-most column exactly matches the sample. nLt is the approximate 
** number of entires whose left-most column is less than the sample. The 
** nDLt column is the approximate number of distinct left-most entries in 
** the index that are less than the sample.
**
** Future versions of SQLite might change to store a string containing
** multiple integers values in the nDLt column of sqlite_stat3.  The first
** integer will be the number of prior index entries that are distinct in
** the left-most column.  The second integer will be the number of prior index
** entries that are distinct in the first two columns.  The third integer
** will be the number of prior index entries that are distinct in the first







|
|
|
|
|
|
|
|
|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
** column contains a single integer which is the (estimated) number of
** rows in the table identified by sqlite_stat1.tbl.
**
** Format for sqlite_stat3:
**
** The sqlite_stat3 table may contain multiple entries for each index.
** The idx column names the index and the tbl column is the table of the
** index.  If the idx and tbl columns are the same, then the sample is
** of the INTEGER PRIMARY KEY.  The sample column is a value taken from
** the left-most column of the index.  The nEq column is the approximate
** number of entires in the index whose left-most column exactly matches
** the sample.  nLt is the approximate number of entires whose left-most
** column is less than the sample.  The nDLt column is the approximate
** number of distinct left-most entries in the index that are less than
** the sample.
**
** Future versions of SQLite might change to store a string containing
** multiple integers values in the nDLt column of sqlite_stat3.  The first
** integer will be the number of prior index entries that are distinct in
** the left-most column.  The second integer will be the number of prior index
** entries that are distinct in the first two columns.  The third integer
** will be the number of prior index entries that are distinct in the first
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
      aRoot[i] = pPK->tnum;
      assert( aRoot[i]>0 );
      if( zWhere ){
        sqlite4NestedParse(pParse,
           "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
        );
      }else{
        /* The sqlite_stat[13] table already exists.  Delete all rows. */
        sqlite4VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
      }
    }
  }

  /* Open the sqlite_stat[13] tables for writing. */
  for(i=0; i<ArraySize(aTable); i++){







|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
      aRoot[i] = pPK->tnum;
      assert( aRoot[i]>0 );
      if( zWhere ){
        sqlite4NestedParse(pParse,
           "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
        );
      }else{
        /* The sqlite_stat[12] table already exists.  Delete all rows. */
        sqlite4VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
      }
    }
  }

  /* Open the sqlite_stat[13] tables for writing. */
  for(i=0; i<ArraySize(aTable); i++){
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
  int mxSample;             /* Maximum number of samples to accumulate */
  int nSample;              /* Current number of samples */
  u32 iPrn;                 /* Pseudo-random number used for sampling */
  struct Stat3Sample {
    void *pKey;                /* Index key for this sample */
    int nKey;                  /* Bytes of pKey in use */
    int nAlloc;                /* Bytes of space allocated at pKey */

    tRowcnt nEq;               /* sqlite_stat3.nEq */
    tRowcnt nLt;               /* sqlite_stat3.nLt */
    tRowcnt nDLt;              /* sqlite_stat3.nDLt */
    u8 isPSample;              /* True if a periodic sample */
    u32 iHash;                 /* Tiebreaker value (pseudo-random) */
  } *a;                     /* An array of samples */
};

#ifdef SQLITE4_ENABLE_STAT3

/*
** Delete a Stat3Accum object.
*/
static void delStat3Accum(void *pCtx, void *pDel){
  sqlite4 *db = (sqlite4*)pCtx;
  Stat3Accum *p = (Stat3Accum*)pDel;
  int i;

  for(i=0; i<p->nSample; i++){
    sqlite4DbFree(db, p->a[i].pKey);
  }
  sqlite4DbFree(db, p);
}

/*
** Implementation of the stat3_init(C,S) SQL function.  The two parameters
** are the number of rows in the table or index (C) and the number of samples
** to accumulate (S).







>




|





<
<
<
|

<
<
<
<
<
<







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
  int mxSample;             /* Maximum number of samples to accumulate */
  int nSample;              /* Current number of samples */
  u32 iPrn;                 /* Pseudo-random number used for sampling */
  struct Stat3Sample {
    void *pKey;                /* Index key for this sample */
    int nKey;                  /* Bytes of pKey in use */
    int nAlloc;                /* Bytes of space allocated at pKey */

    tRowcnt nEq;               /* sqlite_stat3.nEq */
    tRowcnt nLt;               /* sqlite_stat3.nLt */
    tRowcnt nDLt;              /* sqlite_stat3.nDLt */
    u8 isPSample;              /* True if a periodic sample */
    u32 iHash;                 /* Tiebreaker hash */
  } *a;                     /* An array of samples */
};

#ifdef SQLITE4_ENABLE_STAT3




static void delStat3Accum(void *pCtx, void *p){
  sqlite4 *db = (sqlite4*)pCtx;






  sqlite4DbFree(db, p);
}

/*
** Implementation of the stat3_init(C,S) SQL function.  The two parameters
** are the number of rows in the table or index (C) and the number of samples
** to accumulate (S).
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  }else{
    if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
      doInsert = 1;
    }
  }
  if( !doInsert ) return;
  if( p->nSample==p->mxSample ){
    void *pKey = p->a[iMin].pKey;
    int nAlloc = p->a[iMin].nAlloc;
    assert( p->nSample - iMin - 1 >= 0 );
    memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
    pSample = &p->a[p->nSample-1];
    memset(pSample, 0, sizeof(struct Stat3Sample));
    pSample->pKey = pKey;
    pSample->nAlloc = nAlloc;
  }else{
    pSample = &p->a[p->nSample++];
  }

  pKey = sqlite4_value_blob(argv[3], &nKey);
  if( nKey>pSample->nAlloc ){
    sqlite4 *db = sqlite4_context_db_handle(context);







<
<




<
<







294
295
296
297
298
299
300


301
302
303
304


305
306
307
308
309
310
311
  }else{
    if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
      doInsert = 1;
    }
  }
  if( !doInsert ) return;
  if( p->nSample==p->mxSample ){


    assert( p->nSample - iMin - 1 >= 0 );
    memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
    pSample = &p->a[p->nSample-1];
    memset(pSample, 0, sizeof(struct Stat3Sample));


  }else{
    pSample = &p->a[p->nSample++];
  }

  pKey = sqlite4_value_blob(argv[3], &nKey);
  if( nKey>pSample->nAlloc ){
    sqlite4 *db = sqlite4_context_db_handle(context);
417
418
419
420
421
422
423



424
425
426
427
428
429
430
  0,                /* xStep */
  0,                /* xFinalize */
  "stat3_get",      /* zName */
  0,                /* pHash */
  0                 /* pDestructor */
};
#endif /* SQLITE4_ENABLE_STAT3 */




/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */







>
>
>







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  0,                /* xStep */
  0,                /* xFinalize */
  "stat3_get",      /* zName */
  0,                /* pHash */
  0                 /* pDestructor */
};
#endif /* SQLITE4_ENABLE_STAT3 */




/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */
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
#endif

  iIdxCur = pParse->nTab++;
  sqlite4VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int nCol;
    KeyInfo *pKey;

    int regCnt;                  /* Total number of rows in table. */
    int regPrev;                 /* Previous index key read from database */
    int aregCard;                /* Cardinality array registers */
#ifdef SQLITE4_ENABLE_STAT3
    int addrAddimm;              /* Address at top of stat3 output loop */
    int addrIsnull;              /* Another address within the stat3 loop */
#endif

    if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
    VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
    nCol = pIdx->nColumn;


    pKey = sqlite4IndexKeyinfo(pParse, pIdx);
    if( iMem+1+(nCol*2)>pParse->nMem ){
      pParse->nMem = iMem+1+(nCol*2);
    }

    /* Open a cursor to the index to be analyzed. */
    assert( iDb==sqlite4SchemaToIndex(db, pIdx->pSchema) );







>











>
>







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
#endif

  iIdxCur = pParse->nTab++;
  sqlite4VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int nCol;
    KeyInfo *pKey;
    int *aChngAddr;              /* Array of jump instruction addresses */
    int regCnt;                  /* Total number of rows in table. */
    int regPrev;                 /* Previous index key read from database */
    int aregCard;                /* Cardinality array registers */
#ifdef SQLITE4_ENABLE_STAT3
    int addrAddimm;              /* Address at top of stat3 output loop */
    int addrIsnull;              /* Another address within the stat3 loop */
#endif

    if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
    VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
    nCol = pIdx->nColumn;
    aChngAddr = sqlite4DbMallocRaw(db, sizeof(int)*nCol);
    if( aChngAddr==0 ) continue;
    pKey = sqlite4IndexKeyinfo(pParse, pIdx);
    if( iMem+1+(nCol*2)>pParse->nMem ){
      pParse->nMem = iMem+1+(nCol*2);
    }

    /* Open a cursor to the index to be analyzed. */
    assert( iDb==sqlite4SchemaToIndex(db, pIdx->pSchema) );
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
    */
    regCnt = iMem;
    regPrev = iMem+1;
    aregCard = iMem+2;

    sqlite4VdbeAddOp2(v, OP_Integer, 0, regCnt);
    sqlite4VdbeAddOp2(v, OP_Null, 0, regPrev);
#ifdef SQLITE4_ENABLE_STAT3
    sqlite4VdbeAddOp2(v, OP_Null, 0, regSample);
#endif
    for(i=0; i<nCol; i++){
      sqlite4VdbeAddOp2(v, OP_Integer, 1, aregCard+i);
    }

    /* Start the analysis loop. This loop runs through all the entries in
    ** the index b-tree.  */
    endOfLoop = sqlite4VdbeMakeLabel(v);







<

<







544
545
546
547
548
549
550

551

552
553
554
555
556
557
558
    */
    regCnt = iMem;
    regPrev = iMem+1;
    aregCard = iMem+2;

    sqlite4VdbeAddOp2(v, OP_Integer, 0, regCnt);
    sqlite4VdbeAddOp2(v, OP_Null, 0, regPrev);

    sqlite4VdbeAddOp2(v, OP_Null, 0, regSample);

    for(i=0; i<nCol; i++){
      sqlite4VdbeAddOp2(v, OP_Integer, 1, aregCard+i);
    }

    /* Start the analysis loop. This loop runs through all the entries in
    ** the index b-tree.  */
    endOfLoop = sqlite4VdbeMakeLabel(v);
665
666
667
668
669
670
671

672
673
674
675
676
677
678
  sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
  sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
  sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
  if( pParse->nMem<regRec ) pParse->nMem = regRec;
  sqlite4VdbeJumpHere(v, jZeroRows);
}


/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
*/
static void loadAnalysis(Parse *pParse, int iDb){
  Vdbe *v = sqlite4GetVdbe(pParse);







>







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
  sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
  sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
  sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
  if( pParse->nMem<regRec ) pParse->nMem = regRec;
  sqlite4VdbeJumpHere(v, jZeroRows);
}


/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
*/
static void loadAnalysis(Parse *pParse, int iDb){
  Vdbe *v = sqlite4GetVdbe(pParse);
Changes to src/build.c.
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    Schema *pSchema;
    HashElem *p;
    int maxTab = 1;

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

    pParse->iNewidxReg = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, maxTab, pParse->iNewidxReg);
  }

  sqlite4VdbeAddOp2(v, OP_NewIdxid, pParse->iNewidxReg, iDb);







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    Schema *pSchema;
    HashElem *p;
    int maxTab = 1;

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

    pParse->iNewidxReg = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, maxTab, pParse->iNewidxReg);
  }

  sqlite4VdbeAddOp2(v, OP_NewIdxid, pParse->iNewidxReg, iDb);
819
820
821
822
823
824
825

826
827
828
829
830
831
832
833
    {
      int tnum = firstAvailableTableNumber(db, iDb);
      sqlite4VdbeAddOp2(v, OP_Integer, tnum, reg2);
    }
#endif
    sqlite4OpenMasterTable(pParse, iDb);
    sqlite4VdbeAddOp2(v, OP_NewRowid, 0, reg1);

    sqlite4VdbeAddOp3(v, OP_Insert, 0, 0, reg1);
    sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
    sqlite4VdbeAddOp0(v, OP_Close);
  }

  /* Normal (non-error) return. */
  return;








>
|







819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
    {
      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);
  }

  /* Normal (non-error) return. */
  return;

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
    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].iPrimKey = 1;
    pTab->aCol[iCol].notNull = 1;
  }else{
    for(i=0; i<pList->nExpr; i++){
      for(iCol=0; iCol<pTab->nCol; iCol++){
        if( sqlite4_stricmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].iPrimKey = i+1;
        pTab->aCol[iCol].notNull = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }
  pPk = sqlite4CreateIndex(pParse, 0, pList, 0, onError, 0, sortOrder, 1);



  if( iCol>=0 && iCol<pTab->nCol
   && (zType = pTab->aCol[iCol].zType)!=0
   && sqlite4_stricmp(zType, "INTEGER")==0
   && sortOrder==SQLITE4_SO_ASC
   && pPk
  ){







|









|





|
>
>







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
    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( sqlite4_stricmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = i+1;
        pTab->aCol[iCol].notNull = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }
  pPk = sqlite4CreateIndex(
     pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, 1
  );

  if( iCol>=0 && iCol<pTab->nCol
   && (zType = pTab->aCol[iCol].zType)!=0
   && sqlite4_stricmp(zType, "INTEGER")==0
   && sortOrder==SQLITE4_SO_ASC
   && pPk
  ){
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
}

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 nCover,                     /* Number of covered 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(int)*nCover +                 /* Index.aiCover    */
      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->aiCover = (int *)(&pIndex->aiColumn[nCol]);
    pIndex->aSortOrder = (u8 *)(&pIndex->aiCover[nCover]);
    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->nCover = nCover;
    pIndex->onError = (u8)onError;
    pIndex->pSchema = pTab->pSchema;

  }

  *pzExtra = zExtra;
  return pIndex;
}

static int addIndexToHash(sqlite4 *db, Index *pIdx){







<
















<














<
|





<


>







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
}

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;

  }

  *pzExtra = zExtra;
  return pIndex;
}

static int addIndexToHash(sqlite4 *db, Index *pIdx){
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
){
  sqlite4 *db = pParse->db;
  Index *pIndex;                  /* New index */
  char *zExtra;

  assert( !pTab->pIndex || pTab->pIndex->eIndexType!=SQLITE4_INDEX_PRIMARYKEY );
  assert( sqlite4Strlen30("binary")==6 );
  pIndex = newIndex(pParse, pTab, pTab->zName, 1, 0, OE_Abort, 1+6, &zExtra);
  if( pIndex && addIndexToHash(db, pIndex) ){
    sqlite4DbFree(db, pIndex);
    pIndex = 0;
  }
  if( pIndex ){
    pIndex->aiColumn[0] = -1;
    pIndex->azColl[0] = zExtra;







|







1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
){
  sqlite4 *db = pParse->db;
  Index *pIndex;                  /* New index */
  char *zExtra;

  assert( !pTab->pIndex || pTab->pIndex->eIndexType!=SQLITE4_INDEX_PRIMARYKEY );
  assert( sqlite4Strlen30("binary")==6 );
  pIndex = newIndex(pParse, pTab, pTab->zName, 1, OE_Abort, 1+6, &zExtra);
  if( pIndex && addIndexToHash(db, pIndex) ){
    sqlite4DbFree(db, pIndex);
    pIndex = 0;
  }
  if( pIndex ){
    pIndex->aiColumn[0] = -1;
    pIndex->azColl[0] = zExtra;
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
  FKey *pFKey;
  if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
  assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
  pFKey->isDeferred = (u8)isDeferred;
#endif
}

/*
** Cursor iPkCsr is open on a primary key index. This function generates
** code that creates the corresponding covering index record required
** by pIdx by reading values from this cursor. The record is stored in
** register regOut.
*/
void sqlite4EncodeIndexValue(
  Parse *pParse,                  /* Parse context */
  int iPkCsr,                     /* Cursor open on primary key */
  Index *pIdx,                    /* Index to create record for */
  int regOut                      /* Register to write record to */
){
  Vdbe *v = pParse->pVdbe;        /* Generate code into this virtual machine */
  Table *pTab = pIdx->pTable;     /* The table that is indexed */
  int i;                          /* Used to iterate through columns */
  int reg;                        /* Array of pIdx->nCover temp registers */

  reg = sqlite4GetTempRange(pParse, pIdx->nCover);
  for(i=0; i<pIdx->nCover; i++){
    sqlite4ExprCodeGetColumnOfTable(v, pTab, iPkCsr, pIdx->aiCover[i], reg+i);
  }
  sqlite4VdbeAddOp3(v, OP_MakeRecord, reg, pIdx->nCover, regOut);
  sqlite4ReleaseTempRange(pParse, reg, pIdx->nCover);
}

/*
** 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, int bCreate){
  Table *pTab = pIdx->pTable;    /* The table that is indexed */







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







2232
2233
2234
2235
2236
2237
2238

























2239
2240
2241
2242
2243
2244
2245
  FKey *pFKey;
  if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
  assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
  pFKey->isDeferred = (u8)isDeferred;
#endif
}


























/*
** 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, int bCreate){
  Table *pTab = pIdx->pTable;    /* The table that is indexed */
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341

2342
2343
2344
2345
2346
2347
2348

    sqlite4VdbeAddOp2(v, OP_RowKey, iTab, regKey);
    for(i=0; i<pTab->nCol; i++){
      sqlite4VdbeAddOp3(v, OP_Column, iTab, i, regData+i);
    }
    sqlite4Fts5CodeUpdate(pParse, pIdx, pParse->iNewidxReg, regKey, regData, 0);
  }else{
    int regData = 0;
    regKey = sqlite4GetTempRange(pParse, 2);
    sqlite4EncodeIndexKey(pParse, pPk, iTab, pIdx, iIdx, 0, 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, (char *)zErr, P4_STATIC);
      sqlite4VdbeJumpHere(v, addrTest);
    }
    if( pIdx->nCover>0 ){
      regData = regKey+1;
      sqlite4EncodeIndexValue(pParse, iTab, pIdx, regData);
    }
    sqlite4VdbeAddOp3(v, OP_Insert, iIdx, regData, regKey);  
    sqlite4ReleaseTempRange(pParse, regKey, 2);
  }

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


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

/*
** The CreateIndex structure indicated by the first argument contains the







|
|









<
<
<
<
|
<




>







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

    sqlite4VdbeAddOp2(v, OP_RowKey, iTab, regKey);
    for(i=0; i<pTab->nCol; i++){
      sqlite4VdbeAddOp3(v, OP_Column, iTab, i, regData+i);
    }
    sqlite4Fts5CodeUpdate(pParse, pIdx, pParse->iNewidxReg, regKey, regData, 0);
  }else{
    sqlite4GetTempRange(pParse,2);
    regKey = sqlite4GetTempReg(pParse);
    sqlite4EncodeIndexKey(pParse, pPk, iTab, pIdx, iIdx, 0, 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, (char *)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);
}

/*
** The CreateIndex structure indicated by the first argument contains the
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
    sqlite4ErrorMsg(pParse, "virtual tables may not be indexed");
    return 0;
  }

  /* Ensure that the proposed index name is not reserved. */
  assert( pName->z!=0 );
  zName = sqlite4NameFromToken(db, pName);
  if( zName==0 || sqlite4CheckObjectName(pParse, zName) ){
    pTab = 0;
  }

  /* Unless SQLite is currently parsing an existing database schema, check
  ** that there is not already an index or table using the proposed name.  */
  else if( !db->init.busy ){
    char *zDb = db->aDb[iDb].zName;
    if( sqlite4FindTable(db, zName, zDb)!=0 ){
      sqlite4ErrorMsg(pParse, "there is already a table named %s", zName);
    }
    else if( sqlite4FindIndex(db, zName, zDb)!=0 ){
      if( p->bIfnotexist ){
        assert( !db->init.busy );







|
<
<



|







2387
2388
2389
2390
2391
2392
2393
2394


2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
    sqlite4ErrorMsg(pParse, "virtual tables may not be indexed");
    return 0;
  }

  /* Ensure that the proposed index name is not reserved. */
  assert( pName->z!=0 );
  zName = sqlite4NameFromToken(db, pName);
  if( zName==0 || sqlite4CheckObjectName(pParse, zName) ) return 0;



  /* Unless SQLite is currently parsing an existing database schema, check
  ** that there is not already an index or table using the proposed name.  */
  if( !db->init.busy ){
    char *zDb = db->aDb[iDb].zName;
    if( sqlite4FindTable(db, zName, zDb)!=0 ){
      sqlite4ErrorMsg(pParse, "there is already a table named %s", zName);
    }
    else if( sqlite4FindIndex(db, zName, zDb)!=0 ){
      if( p->bIfnotexist ){
        assert( !db->init.busy );
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
    char *zIdx = 0;
    int iDb = 0;

    pTab = createIndexFindTable(pParse, p, &pIdxName, &zIdx, &iDb);
    if( pTab && 0==createIndexAuth(pParse, pTab, zIdx) ){
      int nExtra = sqlite4Fts5IndexSz();
      char *zExtra = 0;
      pIdx = newIndex(pParse, pTab, zIdx, 0, 0, 0, nExtra, &zExtra);
      if( pIdx ){
        pIdx->pFts = (Fts5Index *)zExtra;
        sqlite4Fts5IndexInit(pParse, pIdx, pList);
        pIdx->eIndexType = SQLITE4_INDEX_FTS5;
      }
    }








|







2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
    char *zIdx = 0;
    int iDb = 0;

    pTab = createIndexFindTable(pParse, p, &pIdxName, &zIdx, &iDb);
    if( pTab && 0==createIndexAuth(pParse, pTab, zIdx) ){
      int nExtra = sqlite4Fts5IndexSz();
      char *zExtra = 0;
      pIdx = newIndex(pParse, pTab, zIdx, 0, 0, nExtra, &zExtra);
      if( pIdx ){
        pIdx->pFts = (Fts5Index *)zExtra;
        sqlite4Fts5IndexInit(pParse, pIdx, pList);
        pIdx->eIndexType = SQLITE4_INDEX_FTS5;
      }
    }

2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649


2650
2651
2652

2653
2654

2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
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
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
    sqlite4DbFree(db, zIdx);
  }

  sqlite4ExprListDelete(db, pList);
  sqlite4SrcListDelete(db, p->pTblName);
}

/*
** Parameter zName points to a nul-terminated buffer containing a column
** name. If table pTab has a column of the specified name, return its
** index (the first table column being 0, the next 1 etc.). Or, if there
** is no such column, leave an error in pParse and return -1.
*/
static int findTableColumn(Parse *pParse, Table *pTab, const char *zName){
  int j;
  Column *pTabCol;

  for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
    if( sqlite4_stricmp(zName, pTabCol->zName)==0 ) break;
  }
  if( j>=pTab->nCol ){
    sqlite4ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, zName);
    pParse->checkSchema = 1;
    return -1;
  }

  return j;
}

/*
** 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
** as the table to be indexed.  pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
**
** pList is a list of columns to be indexed.  pList will be NULL if this
** is a primary key or unique-constraint on the most recent column added
** to the table currently under construction.  
**
** If the index is created successfully, return a pointer to the new Index
** structure. This is used by sqlite4AddPrimaryKey() to mark the index
** as the tables primary key (Index.autoIndex==2).
*/
Index *sqlite4CreateIndex(
  Parse *pParse,     /* All information about this parse */
  CreateIndex *pCI,  /* Name of index to create etc. */


  ExprList *pList,   /* A list of columns to be indexed */
  IdList *pCovering, /* Covering list (or NULL) */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */

  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
  int sortOrder,     /* Sort order of primary key when pList==NULL */

  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 */
  sqlite4 *db = pParse->db;
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  ExprListItem *pListItem; /* For looping over pList */
  int nExtra = 0;
  char *zExtra;

  int nCover = 0;
  Token *pStart = 0;
  SrcList *pTblName = 0;

  if( pCI ){
    pStart = &pCI->tCreate;
    pTblName = pCI->pTblName;
  }
  if( pCovering ){
    nCover = pCovering->nId;
    if( nCover==0 ) nCover = pList->nExpr;
  }

  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( SQLITE4_OK!=sqlite4ReadSchema(pParse) ){
    goto exit_create_index;
  }


  /* Find the table that is to be indexed.  Return early if not found. */

  if( pCI ){








    pTab = createIndexFindTable(pParse, pCI, &pName, &zName, &iDb);
    if( !pTab ) goto exit_create_index;

  }else{

    assert( pName==0 );
    assert( pStart==0 );
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  }

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

  /* If pCI==0 it means that we are dealing with a PRIMARY KEY or 
  ** UNIQUE constraint.  We have to invent our own name.  */
  if( pCI==0 ){
    if( !bPrimaryKey ){
      int n;
      Index *pLoop;
      for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
      zName = sqlite4MPrintf(db, "sqlite_%s_unique%d", pTab->zName, n);
    }else{
      zName = sqlite4MPrintf(db, "%s", pTab->zName);







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


















|
>
>

<

>


>















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









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

>

>











|

|







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
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618













2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
    sqlite4DbFree(db, zIdx);
  }

  sqlite4ExprListDelete(db, pList);
  sqlite4SrcListDelete(db, p->pTblName);
}
























/*
** 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
** as the table to be indexed.  pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
**
** pList is a list of columns to be indexed.  pList will be NULL if this
** is a primary key or unique-constraint on the most recent column added
** to the table currently under construction.  
**
** If the index is created successfully, return a pointer to the new Index
** structure. This is used by sqlite4AddPrimaryKey() to mark the index
** as the tables primary key (Index.autoIndex==2).
*/
Index *sqlite4CreateIndex(
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  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 */
  sqlite4 *db = pParse->db;
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  ExprListItem *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( SQLITE4_OK!=sqlite4ReadSchema(pParse) ){
    goto exit_create_index;
  }

  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){
    CreateIndex sCreate;
    sCreate.bUnique = onError;
    sCreate.bIfnotexist = ifNotExist;
    sCreate.tCreate = *pStart;
    sCreate.tName1 = *pName1;
    sCreate.tName2 = *pName2;
    sCreate.pTblName = pTblName;

    pTab = createIndexFindTable(pParse, &sCreate, &pName, &zName, &iDb);
    if( !pTab ) goto exit_create_index;

  }else{

    assert( pName==0 );
    assert( pStart==0 );
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
  }

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

  /* 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==0 ){
    if( !bPrimaryKey ){
      int n;
      Index *pLoop;
      for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
      zName = sqlite4MPrintf(db, "sqlite_%s_unique%d", pTab->zName, n);
    }else{
      zName = sqlite4MPrintf(db, "%s", pTab->zName);
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
      if( ALWAYS(pColl) ){
        nExtra += (1 + sqlite4Strlen30(pColl->zName));
      }
    }
  }

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

  assert( pIndex->eIndexType==SQLITE4_INDEX_USER );
  if( pName==0 ){
    if( bPrimaryKey ){
      pIndex->eIndexType = SQLITE4_INDEX_PRIMARYKEY;
    }else{
      pIndex->eIndexType = SQLITE4_INDEX_UNIQUE;
    }
  }

  /* Scan the names of the columns of the table to be indexed and
  ** load the column indices into the Index structure.  Report an error
  ** if any column is not found.
  **
  ** TODO:  Add a test to make sure that the same column is not named
  ** more than once within the same index.  Only the first instance of
  ** the column will ever be used by the optimizer.
  */
  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){


    char *zColl;                   /* Collation sequence name */






    j = findTableColumn(pParse, pTab, pListItem->zName);

    if( j<0 ) goto exit_create_index;

    pIndex->aiColumn[i] = j;
    if( pListItem->pExpr && pListItem->pExpr->pColl ){
      int nColl;
      zColl = pListItem->pExpr->pColl->zName;
      nColl = sqlite4Strlen30(zColl) + 1;
      assert( nExtra>=nColl );
      memcpy(zExtra, zColl, nColl);







|
<
<




















>
>


>
>
>
>
>
|
>
|
|







2702
2703
2704
2705
2706
2707
2708
2709


2710
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
      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==SQLITE4_INDEX_USER );
  if( pName==0 ){
    if( bPrimaryKey ){
      pIndex->eIndexType = SQLITE4_INDEX_PRIMARYKEY;
    }else{
      pIndex->eIndexType = SQLITE4_INDEX_UNIQUE;
    }
  }

  /* Scan the names of the columns of the table to be indexed and
  ** load the column indices into the Index structure.  Report an error
  ** if any column is not found.
  **
  ** TODO:  Add a test to make sure that the same column is not named
  ** more than once within the same index.  Only the first instance of
  ** the column will ever be used by the optimizer.
  */
  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
    const char *zColName = pListItem->zName;
    Column *pTabCol;
    char *zColl;                   /* Collation sequence name */

    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
      if( sqlite4_stricmp(zColName, pTabCol->zName)==0 ) break;
    }
    if( j>=pTab->nCol ){
      sqlite4ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, zColName);
      pParse->checkSchema = 1;
      goto exit_create_index;
    }
    pIndex->aiColumn[i] = j;
    if( pListItem->pExpr && pListItem->pExpr->pColl ){
      int nColl;
      zColl = pListItem->pExpr->pColl->zName;
      nColl = sqlite4Strlen30(zColl) + 1;
      assert( nExtra>=nColl );
      memcpy(zExtra, zColl, nColl);
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
      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
    pIndex->aSortOrder[i] = (u8)pListItem->sortOrder;
  }
  sqlite4DefaultRowEst(pIndex);

  /* Scan the names of any covered columns. */
  for(i=0; i<nCover; i++){
    if( pCovering->nId ){
      j = findTableColumn(pParse, pTab, pCovering->a[i].zName);
      if( j<0 ) goto exit_create_index;
      pIndex->aiCover[i] = j;
    }else{
      pIndex->aiCover[i] = i;
    }
  }

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a
    ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
    ** a PRIMARY KEY or UNIQUE clause following the column definitions.
    ** i.e. one of:
    **
    ** CREATE TABLE t(x PRIMARY KEY, y);







<
<
<
<
<
<
<
<
<
<
<







2760
2761
2762
2763
2764
2765
2766











2767
2768
2769
2770
2771
2772
2773
      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
    pIndex->aSortOrder[i] = (u8)pListItem->sortOrder;
  }
  sqlite4DefaultRowEst(pIndex);












  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a
    ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
    ** a PRIMARY KEY or UNIQUE clause following the column definitions.
    ** i.e. one of:
    **
    ** CREATE TABLE t(x PRIMARY KEY, y);
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
exit_create_index:
  if( pIndex ){
    sqlite4DbFree(db, pIndex->zColAff);
    sqlite4DbFree(db, pIndex);
  }
  sqlite4ExprListDelete(db, pList);
  sqlite4SrcListDelete(db, pTblName);
  sqlite4IdListDelete(db, pCovering);
  sqlite4DbFree(db, zName);
  return pRet;
}

/*
** Fill the Index.aiRowEst[] array with default information - information
** to be used when we have not run the ANALYZE command.







<







2888
2889
2890
2891
2892
2893
2894

2895
2896
2897
2898
2899
2900
2901
exit_create_index:
  if( pIndex ){
    sqlite4DbFree(db, pIndex->zColAff);
    sqlite4DbFree(db, pIndex);
  }
  sqlite4ExprListDelete(db, pList);
  sqlite4SrcListDelete(db, pTblName);

  sqlite4DbFree(db, zName);
  return pRet;
}

/*
** Fill the Index.aiRowEst[] array with default information - information
** to be used when we have not run the ANALYZE command.
3804
3805
3806
3807
3808
3809
3810

3811
3812
3813
3814
3815
3816
3817
    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->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);







>







3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
    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);
Changes to src/ctime.c.
294
295
296
297
298
299
300



301
302
303
304
305
306
307
  "OMIT_UTF16",
#endif
#ifdef SQLITE4_OMIT_VIEW
  "OMIT_VIEW",
#endif
#ifdef SQLITE4_OMIT_VIRTUALTABLE
  "OMIT_VIRTUALTABLE",



#endif
#ifdef SQLITE4_PERFORMANCE_TRACE
  "PERFORMANCE_TRACE",
#endif
#ifdef SQLITE4_PROXY_DEBUG
  "PROXY_DEBUG",
#endif







>
>
>







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
  "OMIT_UTF16",
#endif
#ifdef SQLITE4_OMIT_VIEW
  "OMIT_VIEW",
#endif
#ifdef SQLITE4_OMIT_VIRTUALTABLE
  "OMIT_VIRTUALTABLE",
#endif
#ifdef SQLITE4_OMIT_XFER_OPT
  "OMIT_XFER_OPT",
#endif
#ifdef SQLITE4_PERFORMANCE_TRACE
  "PERFORMANCE_TRACE",
#endif
#ifdef SQLITE4_PROXY_DEBUG
  "PROXY_DEBUG",
#endif
Changes to src/delete.c.
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    ** regSet. After the scan is complete, the VM will loop through the set 
    ** of keys in the RowSet 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 RowSet"));
    pWInfo = sqlite4WhereBegin(
        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
    );
    if( pWInfo==0 ) goto delete_from_cleanup;
    sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
    sqlite4VdbeAddOp3(v, OP_RowSetAdd, regSet, 0, regKey);
    sqlite4WhereEnd(pWInfo);

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







|







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    ** regSet. After the scan is complete, the VM will loop through the set 
    ** of keys in the RowSet 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 RowSet"));
    pWInfo = sqlite4WhereBegin(
        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK
    );
    if( pWInfo==0 ) goto delete_from_cleanup;
    sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
    sqlite4VdbeAddOp3(v, OP_RowSetAdd, regSet, 0, regKey);
    sqlite4WhereEnd(pWInfo);

    /* Unless this is a view, open cursors for all indexes on the table
Changes to src/env.c.
85
86
87
88
89
90
91

92
93
94
95
96
97
98
**
** This routine is not threadsafe.  It should be called from a single
** thread to initialized the library in a multi-threaded system.  Other
** threads should avoid using the sqlite4_env object until after it has
** completely initialized.
*/
int sqlite4_initialize(sqlite4_env *pEnv){

  int rc;                                      /* Result code */

  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;

  /* If SQLite is already completely initialized, then this call
  ** to sqlite4_initialize() should be a no-op.  But the initialization
  ** must be complete.  So isInit must not be set until the very end







>







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
**
** This routine is not threadsafe.  It should be called from a single
** thread to initialized the library in a multi-threaded system.  Other
** threads should avoid using the sqlite4_env object until after it has
** completely initialized.
*/
int sqlite4_initialize(sqlite4_env *pEnv){
  MUTEX_LOGIC( sqlite4_mutex *pMaster; )       /* The main static mutex */
  int rc;                                      /* Result code */

  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;

  /* If SQLite is already completely initialized, then this call
  ** to sqlite4_initialize() should be a no-op.  But the initialization
  ** must be complete.  So isInit must not be set until the very end
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    sqlite4_mutex_free(pEnv->pFactoryMutex);
    sqlite4_mutex_free(pEnv->pPrngMutex);
    sqlite4_mutex_free(pEnv->pMemMutex);
    pEnv->pMemMutex = 0;
    while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
      KVFactory *pNext = pMkr->pNext;
      sqlite4_free(pEnv, pMkr);
      pEnv->pFactory = pNext;
    }
    sqlite4MutexEnd(pEnv);
    sqlite4MallocEnd(pEnv);
    pEnv->isInit = 0;
  }
  return SQLITE4_OK;
}







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    sqlite4_mutex_free(pEnv->pFactoryMutex);
    sqlite4_mutex_free(pEnv->pPrngMutex);
    sqlite4_mutex_free(pEnv->pMemMutex);
    pEnv->pMemMutex = 0;
    while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
      KVFactory *pNext = pMkr->pNext;
      sqlite4_free(pEnv, pMkr);
      pMkr = pNext;
    }
    sqlite4MutexEnd(pEnv);
    sqlite4MallocEnd(pEnv);
    pEnv->isInit = 0;
  }
  return SQLITE4_OK;
}
Changes to src/expr.c.
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
  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
    sqlite4 *db = pParse->db;
    Table *pTab = p->pSrc->a[0].pTab;
    Expr *pRhs = p->pEList->a[0].pExpr;
    int iCol = pRhs->iColumn;
    CollSeq *pReq;
    char colaff;

    /* 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, pRhs);
    if( !pReq ) pReq = db->pDfltColl;

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

    colaff = (iCol<0) ? SQLITE4_AFF_NUMERIC : pTab->aCol[iCol].affinity;
    if( 0==sqlite4IndexAffinityOk(pX, colaff) ) return 0;

    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      if( (pIdx->aiColumn[0]==iCol)
       && sqlite4FindCollSeq(db, pIdx->azColl[0], 0)==pReq
       && (!bReqUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
      ){
        break;
      }
    }
  }

  return pIdx;
}
#endif /* SQLITE4_OMIT_SUBQUERY */

#ifndef SQLITE4_OMIT_SUBQUERY
/*
** This function is used by the implementation of the IN (...) operator.
** The pX parameter is the expression on the RHS of the IN operator, which
** might be either a list of expressions or a subquery.
**
** The job of this routine is to find or create a b-tree object that can
** be used either to test for membership in the RHS set or to iterate through
** all members of the RHS set, skipping duplicates.
**
** A cursor is opened on the b-tree object that the RHS of the IN operator
** and pX->iTable is set to the index of that cursor.
**
** The returned value of this function indicates the b-tree type, as follows:
**
**   IN_INDEX_ROWID      - The cursor was opened on the PK index of a
**                         table with an implicit integer primary key.
**   IN_INDEX_INDEX_ASC  - The cursor was opened on an ascending index.
**   IN_INDEX_INDEX_DESC - The cursor was opened on a descending index.
**   IN_INDEX_EPH        - The cursor was opened on a specially created and
**                         populated epheremal table.
**
** An existing b-tree might be used if the RHS expression pX is a simple
** subquery such as:
**
**     SELECT <column> FROM <table>
**
** If the RHS of the IN operator is a list or a more complex subquery, then
** an ephemeral table might need to be generated from the RHS and then
** pX->iTable made to point to the ephermeral table instead of an
** existing table.  
**
**
** ITERATING THROUGH SET MEMBERS
** 
**   If the prNotFound parameter is 0, then the b-tree will be used to 
**   iterate through the set members, skipping any duplicates. In this
**   case the piCov parameter is always non-zero. An index on column 
**   <column> of <table> is used in this case if:
**
**     1. The index guarantees the column is unique (i.e. it is a UNIQUE
**        or PRIMARY KEY Index), and
**
**     2. The index uses the same collation sequence as the comparison
**        performed by expression pX.
**
**     3. The index is a covering index for <column> (either because it
**        is a PRIMARY KEY or was created with a COVERING clause).
**
**   Restriction (3) could be removed by the calling code in where.c.
**
**   Before returning, *piCov is set to the column number of <column> in
**   the value associated with the selected covering or primary key index.
**
** SET MEMBERSHIP TESTS

**
** If the prNotFound parameter is not 0, then the b-tree will be used 
** for fast set membership tests. In this case an epheremal table must 
** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
** be found with <column> as its left-most column.
**
** When the b-tree is being used for membership tests, the calling function







|





<




>
|
<















<


<
<
<
|
|
|

|
|
<


<
<
|
|
|
|

|
|



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







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
  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
    sqlite4 *db = pParse->db;
    Table *pTab = p->pSrc->a[0].pTab;
    Expr *pRhs = p->pEList->a[0].pExpr;
    int iCol = pRhs->iColumn;
    CollSeq *pReq;
    char aff;

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


    /* 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);
    if( aff!=SQLITE4_AFF_NONE && aff!=pTab->aCol[iCol].affinity ) return 0;


    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      if( (pIdx->aiColumn[0]==iCol)
       && sqlite4FindCollSeq(db, pIdx->azColl[0], 0)==pReq
       && (!bReqUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
      ){
        break;
      }
    }
  }

  return pIdx;
}
#endif /* SQLITE4_OMIT_SUBQUERY */


/*
** This function is used by the implementation of the IN (...) operator.



** It's job is to find or create a b-tree structure that may be used
** either to test for membership of the (...) set or to iterate through
** its members, skipping duplicates.
**
** The index of the cursor opened on the b-tree (database table, database index 
** or ephermal table) is stored in pX->iTable before this function returns.

** The returned value of this function indicates the b-tree type, as follows:
**


**   IN_INDEX_ROWID - The cursor was opened on a database table.
**   IN_INDEX_INDEX - The cursor was opened on a database index.
**   IN_INDEX_EPH -   The cursor was opened on a specially created and
**                    populated epheremal table.
**
** An existing b-tree may only be used if the SELECT is of the simple
** form:
**
**     SELECT <column> FROM <table>
**








** If the prNotFound parameter is 0, then the b-tree will be used to iterate
** through the set members, skipping any duplicates. In this case an

** epheremal table must be used unless the selected <column> is guaranteed


** to be unique - either because it is an INTEGER PRIMARY KEY or it













** has a UNIQUE constraint or UNIQUE index.
**
** If the prNotFound parameter is not 0, then the b-tree will be used 
** for fast set membership tests. In this case an epheremal table must 
** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
** be found with <column> as its left-most column.
**
** When the b-tree is being used for membership tests, the calling function
1491
1492
1493
1494
1495
1496
1497

1498
1499

1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
**     has_null = <test if data structure contains null>
**     register = 1
**   }
**
** in order to avoid running the <test if data structure contains null>
** test more often than is necessary.
*/

int sqlite4FindInIndex(Parse *pParse, Expr *pX, int *prNotFound, int *piCov){
  Select *p;                            /* SELECT to the right of IN operator */

  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
  int iTab = pParse->nTab++;            /* Cursor of the RHS table */
  int mustBeUnique = (prNotFound==0);   /* True if RHS must be unique */
  Vdbe *v = sqlite4GetVdbe(pParse);     /* Virtual machine being coded */

  assert( pX->op==TK_IN );
  assert( mustBeUnique==(piCov!=0) );

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

  /* Check to see if an existing table or index can be used to
  ** satisfy the query.  This is preferable to generating a new 
  ** ephemeral table.
  */
  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;                  /* Used to iterate through indexes on pTab */
    CollSeq *pReq;                /* Collation sequence for comparison */
    char affinity;                /* Affinity of selected column */
    int affinity_ok;              /* True if the affinity matches */

    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;
    iCol = pExpr->iColumn;
   
    /* Code an OP_VerifyCookie for <table>. */
    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
    sqlite4CodeVerifySchema(pParse, iDb);

    /* 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.  */
    affinity = (iCol<0?SQLITE4_AFF_NUMERIC:pTab->aCol[iCol].affinity);
    affinity_ok = sqlite4IndexAffinityOk(pX, affinity);

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

        if( mustBeUnique ){
          if( pIdx->eIndexType!=SQLITE4_INDEX_PRIMARYKEY ){
            int i;
            for(i=0; i<pIdx->nCover; i++){
              if( pIdx->aiCover[i]==iCol ) break;
            }
            if( i==pIdx->nCover ) continue;
            *piCov = i;
          }else{
            *piCov = iCol;
          }
        }

        iAddr = sqlite4CodeOnce(pParse);
        sqlite4OpenIndex(pParse, iTab, iDb, pIdx, OP_OpenRead);
        assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
        if( iCol<0 ){
          eType = IN_INDEX_ROWID;
        }else{
          eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
        }


        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.
    ** We will have to generate an ephemeral table to do the job.
    */
    u32 savedNQueryLoop = pParse->nQueryLoop;
    int rMayHaveNull = 0;
    eType = IN_INDEX_EPH;
    if( prNotFound ){
      *prNotFound = rMayHaveNull = ++pParse->nMem;
      sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);
    }else{
      testcase( pParse->nQueryLoop>0 );
      pParse->nQueryLoop = 0;
      *piCov = 0;
    }
    sqlite4CodeSubselect(pParse, pX, rMayHaveNull);
    pParse->nQueryLoop = savedNQueryLoop;
  }else{
    pX->iTable = iTab;
  }
  return eType;
}
#endif

/*
** Generate code for scalar subqueries used as a subquery expression, EXISTS,
** or IN operators.  Examples:







>
|
<
>


<



<
<
<
<
<
|


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

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


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







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
**     has_null = <test if data structure contains null>
**     register = 1
**   }
**
** in order to avoid running the <test if data structure contains null>
** test more often than is necessary.
*/
#ifndef SQLITE4_OMIT_SUBQUERY
int sqlite4FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){

  Index *pIdx;
  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
  int iTab = pParse->nTab++;            /* Cursor of the RHS table */

  Vdbe *v = sqlite4GetVdbe(pParse);     /* Virtual machine being coded */

  assert( pX->op==TK_IN );





  assert( prNotFound );

  /* Check to see if an existing table or index can be used to
  ** satisfy the query. This is preferable to generating a new 
  ** ephemeral table.  */












  pIdx = sqlite4FindExistingInIndex(pParse, pX, 0);







  if( pIdx ){



    int iAddr;




    char *pKey;





    int iDb;                      /* aDb[] Index of database containing pIdx */











    iDb = sqlite4SchemaToIndex(pParse->db, pIdx->pSchema);







    pKey = (char *)sqlite4IndexKeyinfo(pParse, pIdx);
    iAddr = sqlite4CodeOnce(pParse);
    sqlite4VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);






    sqlite4VdbeChangeP4(v, -1 , pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pIdx->zName));
    sqlite4VdbeJumpHere(v, iAddr);

    *prNotFound = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);




    pX->iTable = iTab;
  }else{
    /* Could not find an existing table or index to use as the RHS b-tree.
    ** We will have to generate an ephemeral table to do the job.  */

    double savedNQueryLoop = pParse->nQueryLoop;
    int rMayHaveNull = 0;
    eType = IN_INDEX_EPH;

    *prNotFound = rMayHaveNull = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);

    sqlite4CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
    pParse->nQueryLoop = savedNQueryLoop;

  }




  
  return eType;
}
#endif

/*
** Generate code for scalar subqueries used as a subquery expression, EXISTS,
** or IN operators.  Examples:
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
** For a SELECT or EXISTS operator, return the register that holds the
** result.  For IN operators or if an error occurs, the return value is 0.
*/
#ifndef SQLITE4_OMIT_SUBQUERY
int sqlite4CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rMayHaveNull        /* Register that records whether NULLs exist in RHS */

){
  int testAddr = -1;                      /* One-time test address */
  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite4GetVdbe(pParse);
  if( NEVER(v==0) ) return 0;
  sqlite4ExprCachePush(pParse);








|
>







1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
** For a SELECT or EXISTS operator, return the register that holds the
** result.  For IN operators or if an error occurs, the return value is 0.
*/
#ifndef SQLITE4_OMIT_SUBQUERY
int sqlite4CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rMayHaveNull,       /* Register that records whether NULLs exist in RHS */
  int isRowid             /* If true, LHS of IN operator is a rowid */
){
  int testAddr = -1;                      /* One-time test address */
  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite4GetVdbe(pParse);
  if( NEVER(v==0) ) return 0;
  sqlite4ExprCachePush(pParse);

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
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, 1);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;


        sqlite4SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affinity = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        if( sqlite4Select(pParse, pExpr->x.pSelect, &dest) ){
          return 0;
        }







|












>







1603
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
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;

        assert( !isRowid );
        sqlite4SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affinity = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        if( sqlite4Select(pParse, pExpr->x.pSelect, &dest) ){
          return 0;
        }
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        ExprListItem *pItem;
        int r1, r2, r3, r4;

        if( !affinity ){
          affinity = SQLITE4_AFF_NONE;
        }
        keyInfo.aColl[0] = sqlite4ExprCollSeq(pParse, pExpr->pLeft);

        /* Loop through each expression in <exprlist>. */







|







1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        ExprListItem *pItem;
        int r1, r2, r3;

        if( !affinity ){
          affinity = SQLITE4_AFF_NONE;
        }
        keyInfo.aColl[0] = sqlite4ExprCollSeq(pParse, pExpr->pLeft);

        /* Loop through each expression in <exprlist>. */
1765
1766
1767
1768
1769
1770
1771



1772





1773
1774
1775
1776
1777
1778


1779
1780
1781
1782

1783

1784
1785
1786
1787
1788
1789
1790
          */
          if( testAddr>=0 && !sqlite4ExprIsConstant(pE2) ){
            sqlite4VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */



          r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);





          r4 = sqlite4GetTempReg(pParse);
          sqlite4VdbeAddOp2(v, OP_MakeKey, pExpr->iTable, r4);
          sqlite4VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
          sqlite4ExprCacheAffinityChange(pParse, r3, 1);
          sqlite4VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r4);
          sqlite4ReleaseTempReg(pParse, r4);


        }
        sqlite4ReleaseTempReg(pParse, r1);
        sqlite4ReleaseTempReg(pParse, r2);
      }

      sqlite4VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);

      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
      /* If this has to be a scalar SELECT.  Generate code to put the







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




>
|
>







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
          */
          if( testAddr>=0 && !sqlite4ExprIsConstant(pE2) ){
            sqlite4VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */
          if( isRowid && sqlite4ExprIsInteger(pE2, &iValToIns) ){
            sqlite4VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
          }else{
            r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);
            if( isRowid ){
              sqlite4VdbeAddOp2(v, OP_MustBeInt, r3,
                                sqlite4VdbeCurrentAddr(v)+2);
              sqlite4VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
            }else{
              int r4 = sqlite4GetTempReg(pParse);
              sqlite4VdbeAddOp2(v, OP_MakeKey, pExpr->iTable, r4);
              sqlite4VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
              sqlite4ExprCacheAffinityChange(pParse, r3, 1);
              sqlite4VdbeAddOp3(v, OP_IdxInsert, pExpr->iTable, r2, r4);
              sqlite4ReleaseTempReg(pParse, r4);
            }
          }
        }
        sqlite4ReleaseTempReg(pParse, r1);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      if( !isRowid ){
        sqlite4VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
      }
      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
      /* If this has to be a scalar SELECT.  Generate code to put the
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880

  /* Compute the RHS.   After this step, the table with cursor
  ** pExpr->iTable will contains the values that make up the RHS.
  */
  v = pParse->pVdbe;
  assert( v!=0 );       /* OOM detected prior to this routine */
  VdbeNoopComment((v, "begin IN expr"));
  eType = sqlite4FindInIndex(pParse, pExpr, &rRhsHasNull, 0);

  /* Figure out the affinity to use to create a key from the results
  ** of the expression. affinityStr stores a static string suitable for
  ** P4 of OP_MakeRecord.
  */
  affinity = comparisonAffinity(pExpr);








|







1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793

  /* Compute the RHS.   After this step, the table with cursor
  ** pExpr->iTable will contains the values that make up the RHS.
  */
  v = pParse->pVdbe;
  assert( v!=0 );       /* OOM detected prior to this routine */
  VdbeNoopComment((v, "begin IN expr"));
  eType = sqlite4FindInIndex(pParse, pExpr, &rRhsHasNull);

  /* Figure out the affinity to use to create a key from the results
  ** of the expression. affinityStr stores a static string suitable for
  ** P4 of OP_MakeRecord.
  */
  affinity = comparisonAffinity(pExpr);

2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
  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 if( IsKvstore(pTab) ){
    int aOp[2] = { OP_RowKey, OP_RowData };
    assert( iCol==0 || iCol==1 );
    sqlite4VdbeAddOp2(v, aOp[iCol], 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);
  }







<
<
<
<







2087
2088
2089
2090
2091
2092
2093




2094
2095
2096
2097
2098
2099
2100
  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);
  }
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      inReg = sqlite4CodeSubselect(pParse, pExpr, 0);
      break;
    }
    case TK_IN: {
      int destIfFalse = sqlite4VdbeMakeLabel(v);
      int destIfNull = sqlite4VdbeMakeLabel(v);
      sqlite4VdbeAddOp2(v, OP_Null, 0, target);
      sqlite4ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);







|







2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      inReg = sqlite4CodeSubselect(pParse, pExpr, 0, 0);
      break;
    }
    case TK_IN: {
      int destIfFalse = sqlite4VdbeMakeLabel(v);
      int destIfNull = sqlite4VdbeMakeLabel(v);
      sqlite4VdbeAddOp2(v, OP_Null, 0, target);
      sqlite4ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
Changes to src/fkey.c.
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
  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, 0);
  if( nIncr>0 && pFKey->isDeferred==0 ){
    sqlite4ParseToplevel(pParse)->mayAbort = 1;
  }
  sqlite4VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
  if( pWInfo ){
    sqlite4WhereEnd(pWInfo);
  }







|







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
  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);
  }
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
      /* 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 ? !sqlite4_stricmp(pCol->zName,zKey) : pCol->iPrimKey>0) ){
              if( aChange[iKey]>=0 ) return 1;
            }
          }
        }
      }
    }
  }







|







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
      /* 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 ? !sqlite4_stricmp(pCol->zName, zKey) : pCol->isPrimKey) ){
              if( aChange[iKey]>=0 ) return 1;
            }
          }
        }
      }
    }
  }
Changes to src/fts5.c.
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
        int iOff = 0;
        int nStream = 0;
        int nAlloc;

        /* If pnRow is not NULL, then this is the global record. Read the
        ** number of documents in the table from the start of the record. */
        if( pnRow ){
          iOff += sqlite4GetVarint64(&aData[iOff], nData-iOff, (u64 *)pnRow);
        }
        iOff += getVarint32(&aData[iOff], nStream);
        nAlloc = (nStream < nMinStream ? nMinStream : nStream);

        pSz = sqlite4DbMallocZero(db, 
            sizeof(Fts5Size) + sizeof(i64) * pInfo->nCol * nAlloc
        );
        if( pSz==0 ){
          rc = SQLITE4_NOMEM;
        }else{
          int iCol = 0;
          pSz->aSz = (i64 *)&pSz[1];
          pSz->nCol = pInfo->nCol;
          pSz->nStream = nAlloc;
          while( iOff<nData ){
            int i;
            i64 *aSz = &pSz->aSz[iCol*nAlloc];
            for(i=0; i<nStream; i++){
              iOff += sqlite4GetVarint64(&aData[iOff],nData-iOff,(u64*)&aSz[i]);
            }
            iCol++;
          }
        }
      }
    }
    sqlite4KVCursorClose(pCsr);







|


















|







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
        int iOff = 0;
        int nStream = 0;
        int nAlloc;

        /* If pnRow is not NULL, then this is the global record. Read the
        ** number of documents in the table from the start of the record. */
        if( pnRow ){
          iOff += sqlite4GetVarint(&aData[iOff], (u64 *)pnRow);
        }
        iOff += getVarint32(&aData[iOff], nStream);
        nAlloc = (nStream < nMinStream ? nMinStream : nStream);

        pSz = sqlite4DbMallocZero(db, 
            sizeof(Fts5Size) + sizeof(i64) * pInfo->nCol * nAlloc
        );
        if( pSz==0 ){
          rc = SQLITE4_NOMEM;
        }else{
          int iCol = 0;
          pSz->aSz = (i64 *)&pSz[1];
          pSz->nCol = pInfo->nCol;
          pSz->nStream = nAlloc;
          while( iOff<nData ){
            int i;
            i64 *aSz = &pSz->aSz[iCol*nAlloc];
            for(i=0; i<nStream; i++){
              iOff += sqlite4GetVarint(&aData[iOff], (u64*)&aSz[i]);
            }
            iCol++;
          }
        }
      }
    }
    sqlite4KVCursorClose(pCsr);
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
  i64 nRow, 
  u8 *a                           /* Space to serialize record in */
){
  int iOff = 0;
  int iCol;

  if( nRow>=0 ){
    iOff += sqlite4PutVarint64(&a[iOff], nRow);
  }
  iOff += sqlite4PutVarint64(&a[iOff], pSz->nStream);

  for(iCol=0; iCol<pSz->nCol; iCol++){
    int i;
    for(i=0; i<pSz->nStream; i++){
      iOff += sqlite4PutVarint64(&a[iOff], pSz->aSz[iCol*pSz->nStream+i]);
    }
  }

  return sqlite4KVStoreReplace(p, aKey, nKey, a, iOff);
}

static int fts5CsrLoadGlobal(Fts5Cursor *pCsr){







|

|




|







1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
  i64 nRow, 
  u8 *a                           /* Space to serialize record in */
){
  int iOff = 0;
  int iCol;

  if( nRow>=0 ){
    iOff += sqlite4PutVarint(&a[iOff], nRow);
  }
  iOff += sqlite4PutVarint(&a[iOff], pSz->nStream);

  for(iCol=0; iCol<pSz->nCol; iCol++){
    int i;
    for(i=0; i<pSz->nStream; i++){
      iOff += sqlite4PutVarint(&a[iOff], pSz->aSz[iCol*pSz->nStream+i]);
    }
  }

  return sqlite4KVStoreReplace(p, aKey, nKey, a, iOff);
}

static int fts5CsrLoadGlobal(Fts5Cursor *pCsr){
2825
2826
2827
2828
2829
2830
2831




2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
        rc = sqlite4Fts5Pk(pCsr, pInfo->iTbl, &aKey, &nKey);
        if( rc==SQLITE4_OK ){
          rc = sqlite4KVCursorSeek(pCsr->pCsr, aKey, nKey, 0);
          if( rc==SQLITE4_NOTFOUND ){
            rc = SQLITE4_CORRUPT_BKPT;
          }
        }





        if( rc==SQLITE4_OK ){
          int i;
          RowDecoder *pCodec;   /* The decoder object */

          rc = sqlite4VdbeDecoderCreate(db,0, pCsr->pCsr, pInfo->nCol, &pCodec);
          for(i=0; rc==SQLITE4_OK && i<pInfo->nCol; i++){
            rc = sqlite4VdbeDecoderGetColumn(pCodec, i, 0, &pCsr->aMem[i]);
          }
          sqlite4VdbeDecoderDestroy(pCodec);
        }

        if( rc==SQLITE4_OK ) pCsr->bMemValid = 1;
      }
    }

    if( rc==SQLITE4_OK ){







>
>
>
>



|

|

|

|







2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
        rc = sqlite4Fts5Pk(pCsr, pInfo->iTbl, &aKey, &nKey);
        if( rc==SQLITE4_OK ){
          rc = sqlite4KVCursorSeek(pCsr->pCsr, aKey, nKey, 0);
          if( rc==SQLITE4_NOTFOUND ){
            rc = SQLITE4_CORRUPT_BKPT;
          }
        }

        if( rc==SQLITE4_OK ){
          rc = sqlite4KVCursorData(pCsr->pCsr, 0, -1, &aData, &nData);
        }

        if( rc==SQLITE4_OK ){
          int i;
          ValueDecoder *pCodec;   /* The decoder object */

          rc = sqlite4VdbeCreateDecoder(db, aData, nData, pInfo->nCol, &pCodec);
          for(i=0; rc==SQLITE4_OK && i<pInfo->nCol; i++){
            rc = sqlite4VdbeDecodeValue(pCodec, i, 0, &pCsr->aMem[i]);
          }
          sqlite4VdbeDestroyDecoder(pCodec);
        }

        if( rc==SQLITE4_OK ) pCsr->bMemValid = 1;
      }
    }

    if( rc==SQLITE4_OK ){
Changes to src/fts5func.c.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** found in:
**
**   Stephen Robertson and Hugo Zaragoza: "The Probablistic Relevance
**   Framework: BM25 and Beyond", 2009.
*/

#include "sqliteInt.h"
#include <math.h>                 // temporary: For log() */

static char fts5Tolower(char c){
  if( c>='A' && c<='Z' ) c = c + ('a' - 'A');
  return c;
}

static int fts5SimpleCreate(







|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** found in:
**
**   Stephen Robertson and Hugo Zaragoza: "The Probablistic Relevance
**   Framework: BM25 and Beyond", 2009.
*/

#include "sqliteInt.h"
#include <math.h>                 /* temporary: For log() */

static char fts5Tolower(char c){
  if( c>='A' && c<='Z' ) c = c + ('a' - 'A');
  return c;
}

static int fts5SimpleCreate(
Changes to src/func.c.
795
796
797
798
799
800
801







802
803
804
805
806
807
808
  */
  n = sqlite4_value_int(argv[0]);
  sqlite4_result_text(context, sqlite4_compileoption_get(n), -1,
                      SQLITE4_STATIC, 0);
}
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */








/*
** EXPERIMENTAL - This is not an official function.  The interface may
** change.  This function may disappear.  Do not write code that depends
** on this function.
**
** Implementation of the QUOTE() function.  This function takes a single
** argument.  If the argument is numeric, the return value is the same as







>
>
>
>
>
>
>







795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
  */
  n = sqlite4_value_int(argv[0]);
  sqlite4_result_text(context, sqlite4_compileoption_get(n), -1,
                      SQLITE4_STATIC, 0);
}
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */

/* Array for converting from half-bytes (nybbles) into ASCII hex
** digits. */
static const char hexdigits[] = {
  '0', '1', '2', '3', '4', '5', '6', '7',
  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 
};

/*
** EXPERIMENTAL - This is not an official function.  The interface may
** change.  This function may disappear.  Do not write code that depends
** on this function.
**
** Implementation of the QUOTE() function.  This function takes a single
** argument.  If the argument is numeric, the return value is the same as
818
819
820
821
822
823
824
825
826
827
828

829
830

831
832


833
834
835
836
837
838
839
    case SQLITE4_FLOAT: {
      sqlite4_result_value(context, argv[0]);
      break;
    }
    case SQLITE4_BLOB: {
      int nBlob;
      char *zText = 0;
      const char *zBlob = sqlite4_value_blob(argv[0], &nBlob);
      zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); 
      if( zText ){
        zText[0] = 'x';

        zText[1] = '\'';
        sqlite4BlobToHex(nBlob, (const u8*)zBlob, zText+2);

        zText[(nBlob*2)+2] = '\'';
        zText[(nBlob*2)+3] = 0;


        sqlite4_result_text(context, zText, -1, SQLITE4_TRANSIENT, 0);
        sqlite4_free(sqlite4_context_env(context), zText);
      }
      break;
    }
    case SQLITE4_TEXT: {
      int i,j;







|


|
>
|
|
>

|
>
>







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
    case SQLITE4_FLOAT: {
      sqlite4_result_value(context, argv[0]);
      break;
    }
    case SQLITE4_BLOB: {
      int nBlob;
      char *zText = 0;
      char const *zBlob = sqlite4_value_blob(argv[0], &nBlob);
      zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); 
      if( zText ){
        int i;
        for(i=0; i<nBlob; i++){
          zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
          zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
        }
        zText[(nBlob*2)+2] = '\'';
        zText[(nBlob*2)+3] = '\0';
        zText[0] = 'x';
        zText[1] = '\'';
        sqlite4_result_text(context, zText, -1, SQLITE4_TRANSIENT, 0);
        sqlite4_free(sqlite4_context_env(context), zText);
      }
      break;
    }
    case SQLITE4_TEXT: {
      int i,j;
873
874
875
876
877
878
879
880
881
882
883
884
885
886





887
888
889
890
891
892
893
static void hexFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  int i, n;
  const unsigned char *pBlob;
  char *zHex;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  pBlob = sqlite4_value_blob(argv[0], &n);
  zHex = contextMalloc(context, ((i64)n)*2 + 1);
  if( zHex ){
    sqlite4BlobToHex(n, (const u8*)pBlob, zHex);





    sqlite4_result_text(context, zHex, n*2, SQLITE4_DYNAMIC, 0);
  }
}

/*
** The replace() function.  Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived







|



|

|
>
>
>
>
>







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
static void hexFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  int i, n;
  const unsigned char *pBlob;
  char *zHex, *z;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  pBlob = sqlite4_value_blob(argv[0], &n);
  z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
  if( zHex ){
    for(i=0; i<n; i++, pBlob++){
      unsigned char c = *pBlob;
      *(z++) = hexdigits[(c>>4)&0xf];
      *(z++) = hexdigits[c&0xf];
    }
    *z = 0;
    sqlite4_result_text(context, zHex, n*2, SQLITE4_DYNAMIC, 0);
  }
}

/*
** The replace() function.  Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
Changes to src/insert.c.
609
610
611
612
613
614
615

















616
617
618
619
620
621
622

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


















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







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







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

  /* 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 SQLITE4_OMIT_XFER_OPT
  /* If the statement is of the form
  **
  **       INSERT INTO <table1> SELECT * FROM <table2>;
  **
  ** Then special optimizations can be applied that make the transfer
  ** very fast and which reduce fragmentation of indices.
  **
  ** This is the 2nd template.
  */
  if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
    assert( !pTrigger );
    assert( pList==0 );
    goto insert_end;
  }
#endif /* SQLITE4_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
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
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  int i;
  Vdbe *v;
  Index *pIdx;
  u8 pik_flags;
  int regRec;
  int regCover;

  v = sqlite4GetVdbe(pParse);
  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. 
  ** This OP_MakeRecord also serves to apply affinities to the array of
  ** input registers at regContent. For this reason it must be executed 
  ** before any MakeRecord instructions used to create covering index
  ** records.  */
  regRec = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, regContent, pTab->nCol, regRec);
  sqlite4TableAffinityStr(v, pTab);
  sqlite4ExprCacheAffinityChange(pParse, regContent, pTab->nCol);

  regCover = sqlite4GetTempReg(pParse);

  /* Write the entry to each index. */
  for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    assert( pIdx->eIndexType!=SQLITE4_INDEX_PRIMARYKEY || aRegIdx[i] );
    if( pIdx->eIndexType==SQLITE4_INDEX_FTS5 ){
      int iPK;
      sqlite4FindPrimaryKey(pTab, &iPK);
      sqlite4Fts5CodeUpdate(pParse, pIdx, 0, aRegIdx[iPK], regContent, 0);
    }
    else if( aRegIdx[i] ){
      int regData = 0;
      int flags = 0;
      if( pIdx->eIndexType==SQLITE4_INDEX_PRIMARYKEY ){
        regData = regRec;
        flags = pik_flags;
      }else if( pIdx->nCover>0 ){
        int nByte = sizeof(int)*pIdx->nCover;
        int *aiPermute = (int *)sqlite4DbMallocRaw(pParse->db, nByte);

        if( aiPermute ){
          memcpy(aiPermute, pIdx->aiCover, nByte);
          sqlite4VdbeAddOp4(
              v, OP_Permutation, pIdx->nCover, 0, 0,
              (char*)aiPermute, P4_INTARRAY
          );
        }
        regData = regCover;
        sqlite4VdbeAddOp3(v, OP_MakeRecord, regContent, pIdx->nCover, regData);
      }
      sqlite4VdbeAddOp3(v, OP_Insert, baseCur+i, regData, aRegIdx[i]);
      sqlite4VdbeChangeP5(v, flags);
    }
  }
}

/*
** Generate code that will open cursors for a table and for all







<











|
<
<
<
<





<
<














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







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
  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( 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){
    assert( pIdx->eIndexType!=SQLITE4_INDEX_PRIMARYKEY || aRegIdx[i] );
    if( pIdx->eIndexType==SQLITE4_INDEX_FTS5 ){
      int iPK;
      sqlite4FindPrimaryKey(pTab, &iPK);
      sqlite4Fts5CodeUpdate(pParse, pIdx, 0, aRegIdx[iPK], regContent, 0);
    }
    else if( aRegIdx[i] ){
      int regData = 0;
      int flags = 0;
      if( pIdx->eIndexType==SQLITE4_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
1522
1523
1524
1525
1526
1527
1528
































































































































































































































































































































** The following global variable is incremented whenever the
** transfer optimization is used.  This is used for testing
** purposes only - to make sure the transfer optimization really
** is happening when it is suppose to.
*/
int sqlite4_xferopt_count;
#endif /* SQLITE4_TEST */







































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
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
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
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
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
** The following global variable is incremented whenever the
** transfer optimization is used.  This is used for testing
** purposes only - to make sure the transfer optimization really
** is happening when it is suppose to.
*/
int sqlite4_xferopt_count;
#endif /* SQLITE4_TEST */


#ifndef SQLITE4_OMIT_XFER_OPT
/*
** Check to collation names to see if they are compatible.
*/
static int xferCompatibleCollation(const char *z1, const char *z2){
  if( z1==0 ){
    return z2==0;
  }
  if( z2==0 ){
    return 0;
  }
  return sqlite4_stricmp(z1, z2)==0;
}


/*
** Check to see if index pSrc is compatible as a source of data
** for index pDest in an insert transfer optimization.  The rules
** for a compatible index:
**
**    *   The index is over the same set of columns
**    *   The same DESC and ASC markings occurs on all columns
**    *   The same onError processing (OE_Abort, OE_Ignore, etc)
**    *   The same collating sequence on each column
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
  int i;
  assert( pDest && pSrc );
  assert( pDest->pTable!=pSrc->pTable );
  if( pDest->nColumn!=pSrc->nColumn ){
    return 0;   /* Different number of columns */
  }
  if( pDest->onError!=pSrc->onError ){
    return 0;   /* Different conflict resolution strategies */
  }
  for(i=0; i<pSrc->nColumn; i++){
    if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
      return 0;   /* Different columns indexed */
    }
    if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
      return 0;   /* Different sort orders */
    }
    if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
      return 0;   /* Different collating sequences */
    }
  }

  /* If no test above fails then the indices must be compatible */
  return 1;
}

/*
** Attempt the transfer optimization on INSERTs of the form
**
**     INSERT INTO tab1 SELECT * FROM tab2;
**
** The xfer optimization transfers raw records from tab2 over to tab1.  
** Columns are not decoded and reassemblied, which greatly improves
** performance.  Raw index records are transferred in the same way.
**
** The xfer optimization is only attempted if tab1 and tab2 are compatible.
** There are lots of rules for determining compatibility - see comments
** embedded in the code for details.
**
** This routine returns TRUE if the optimization is guaranteed to be used.
** Sometimes the xfer optimization will only work if the destination table
** is empty - a factor that can only be determined at run-time.  In that
** case, this routine generates code for the xfer optimization but also
** does a test to see if the destination table is empty and jumps over the
** xfer optimization code if the test fails.  In that case, this routine
** returns FALSE so that the caller will know to go ahead and generate
** an unoptimized transfer.  This routine also returns FALSE if there
** is no chance that the xfer optimization can be applied.
**
** This optimization is particularly useful at making VACUUM run faster.
*/
static int xferOptimization(
  Parse *pParse,        /* Parser context */
  Table *pDest,         /* The table we are inserting into */
  Select *pSelect,      /* A SELECT statement to use as the data source */
  int onError,          /* How to handle constraint errors */
  int iDbDest           /* The database of pDest */
){
  ExprList *pEList;                /* The result set of the SELECT */
  Table *pSrc;                     /* The table in the FROM clause of SELECT */
  Index *pSrcIdx, *pDestIdx;       /* Source and destination indices */
  struct SrcList_item *pItem;      /* An element of pSelect->pSrc */
  int i;                           /* Loop counter */
  int iDbSrc;                      /* The database of pSrc */
  int iSrc, iDest;                 /* Cursors from source and destination */
  int addr1, addr2;                /* Loop addresses */
  int emptyDestTest;               /* Address of test for empty pDest */
  int emptySrcTest;                /* Address of test for empty pSrc */
  Vdbe *v;                         /* The VDBE we are building */
  KeyInfo *pKey;                   /* Key information for an index */
  int regAutoinc;                  /* Memory register used by AUTOINC */
  int destHasUniqueIdx = 0;        /* True if pDest has a UNIQUE index */
  int regData, regRowid, regKey;   /* Registers holding data and rowid */

  if( pSelect==0 ){
    return 0;   /* Must be of the form  INSERT INTO ... SELECT ... */
  }
  if( sqlite4TriggerList(pParse, pDest) ){
    return 0;   /* tab1 must not have triggers */
  }
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if( pDest->tabFlags & TF_Virtual ){
    return 0;   /* tab1 must not be a virtual table */
  }
#endif
  if( onError==OE_Default ){
    if( pDest->iPKey>=0 ) onError = pDest->keyConf;
    if( onError==OE_Default ) onError = OE_Abort;
  }
  assert(pSelect->pSrc);   /* allocated even if there is no FROM clause */
  if( pSelect->pSrc->nSrc!=1 ){
    return 0;   /* FROM clause must have exactly one term */
  }
  if( pSelect->pSrc->a[0].pSelect ){
    return 0;   /* FROM clause cannot contain a subquery */
  }
  if( pSelect->pWhere ){
    return 0;   /* SELECT may not have a WHERE clause */
  }
  if( pSelect->pOrderBy ){
    return 0;   /* SELECT may not have an ORDER BY clause */
  }
  /* Do not need to test for a HAVING clause.  If HAVING is present but
  ** there is no ORDER BY, we will get an error. */
  if( pSelect->pGroupBy ){
    return 0;   /* SELECT may not have a GROUP BY clause */
  }
  if( pSelect->pLimit ){
    return 0;   /* SELECT may not have a LIMIT clause */
  }
  assert( pSelect->pOffset==0 );  /* Must be so if pLimit==0 */
  if( pSelect->pPrior ){
    return 0;   /* SELECT may not be a compound query */
  }
  if( pSelect->selFlags & SF_Distinct ){
    return 0;   /* SELECT may not be DISTINCT */
  }
  pEList = pSelect->pEList;
  assert( pEList!=0 );
  if( pEList->nExpr!=1 ){
    return 0;   /* The result set must have exactly one column */
  }
  assert( pEList->a[0].pExpr );
  if( pEList->a[0].pExpr->op!=TK_ALL ){
    return 0;   /* The result set must be the special operator "*" */
  }

  /* At this point we have established that the statement is of the
  ** correct syntactic form to participate in this optimization.  Now
  ** we have to check the semantics.
  */
  pItem = pSelect->pSrc->a;
  pSrc = sqlite4LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
  if( pSrc==0 ){
    return 0;   /* FROM clause does not contain a real table */
  }
  if( pSrc==pDest ){
    return 0;   /* tab1 and tab2 may not be the same table */
  }
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if( pSrc->tabFlags & TF_Virtual ){
    return 0;   /* tab2 must not be a virtual table */
  }
#endif
  if( pSrc->pSelect ){
    return 0;   /* tab2 may not be a view */
  }
  if( pDest->nCol!=pSrc->nCol ){
    return 0;   /* Number of columns must be the same in tab1 and tab2 */
  }
  if( pDest->iPKey!=pSrc->iPKey ){
    return 0;   /* Both tables must have the same INTEGER PRIMARY KEY */
  }
  for(i=0; i<pDest->nCol; i++){
    if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){
      return 0;    /* Affinity must be the same on all columns */
    }
    if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){
      return 0;    /* Collating sequence must be the same on all columns */
    }
    if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){
      return 0;    /* tab2 must be NOT NULL if tab1 is */
    }
  }
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    if( pDestIdx->onError!=OE_None ){
      destHasUniqueIdx = 1;
    }
    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    if( pSrcIdx==0 ){
      return 0;    /* pDestIdx has no corresponding index in pSrc */
    }
  }
#ifndef SQLITE4_OMIT_CHECK
  if( pDest->pCheck && sqlite4ExprCompare(pSrc->pCheck, pDest->pCheck) ){
    return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
  }
#endif
#ifndef SQLITE4_OMIT_FOREIGN_KEY
  /* Disallow the transfer optimization if the destination table constains
  ** any foreign key constraints.  This is more restrictive than necessary.
  ** But the main beneficiary of the transfer optimization is the VACUUM 
  ** command, and the VACUUM command disables foreign key constraints.  So
  ** the extra complication to make this rule less restrictive is probably
  ** not worth the effort.  Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
  */
  if( (pParse->db->flags & SQLITE4_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 SQLITE4_TEST
  sqlite4_xferopt_count++;
#endif
  iDbSrc = sqlite4SchemaToIndex(pParse->db, pSrc->pSchema);
  v = sqlite4GetVdbe(pParse);
  sqlite4CodeVerifySchema(pParse, iDbSrc);
  iSrc = pParse->nTab++;
  iDest = pParse->nTab++;
  regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
  sqlite4OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
  if( (pDest->iPKey<0 && pDest->pIndex!=0)          /* (1) */
   || destHasUniqueIdx                              /* (2) */
   || (onError!=OE_Abort && onError!=OE_Rollback)   /* (3) */
  ){
    /* In some circumstances, we are able to run the xfer optimization
    ** only if the destination table is initially empty.  This code makes
    ** that determination.  Conditions under which the destination must
    ** be empty:
    **
    ** (1) There is no INTEGER PRIMARY KEY but there are indices.
    **     (If the destination is not initially empty, the rowid fields
    **     of index entries might need to change.)
    **
    ** (2) The destination has a unique index.  (The xfer optimization 
    **     is unable to test uniqueness.)
    **
    ** (3) onError is something other than OE_Abort and OE_Rollback.
    */
    addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iDest, 0);
    emptyDestTest = sqlite4VdbeAddOp2(v, OP_Goto, 0, 0);
    sqlite4VdbeJumpHere(v, addr1);
  }else{
    emptyDestTest = 0;
  }
  sqlite4OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
  emptySrcTest = sqlite4VdbeAddOp2(v, OP_Rewind, iSrc, 0);
  regKey = sqlite4GetTempReg(pParse);
  regData = sqlite4GetTempReg(pParse);
  regRowid = sqlite4GetTempReg(pParse);
  if( pDest->iPKey>=0 ){
    addr1 = sqlite4VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
    addr2 = sqlite4VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
    sqlite4HaltConstraint(
        pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
    sqlite4VdbeJumpHere(v, addr2);
    autoIncStep(pParse, regAutoinc, regRowid);
  }else if( pDest->pIndex==0 ){
    addr1 = sqlite4VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
  }else{
    addr1 = sqlite4VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
    assert( (pDest->tabFlags & TF_Autoincrement)==0 );
  }
  sqlite4VdbeAddOp2(v, OP_RowData, iSrc, regData);
  sqlite4VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
  sqlite4VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_APPEND);
  sqlite4VdbeChangeP4(v, -1, pDest->zName, 0);
  sqlite4VdbeAddOp2(v, OP_Next, iSrc, addr1);
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );
    sqlite4VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite4VdbeAddOp2(v, OP_Close, iDest, 0);
    pKey = sqlite4IndexKeyinfo(pParse, pSrcIdx);
    sqlite4VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
                      (char*)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pSrcIdx->zName));
    pKey = sqlite4IndexKeyinfo(pParse, pDestIdx);
    sqlite4VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
                      (char*)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pDestIdx->zName));
    addr1 = sqlite4VdbeAddOp2(v, OP_Rewind, iSrc, 0);
    sqlite4VdbeAddOp2(v, OP_RowKey, iSrc, regKey);
    sqlite4VdbeAddOp2(v, OP_RowData, iSrc, regData);
    sqlite4VdbeAddOp3(v, OP_IdxInsert, iDest, regKey, regData);
    sqlite4VdbeChangeP5(v, OPFLAG_APPENDBIAS);
    sqlite4VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
    sqlite4VdbeJumpHere(v, addr1);
  }
  sqlite4VdbeJumpHere(v, emptySrcTest);
  sqlite4ReleaseTempReg(pParse, regRowid);
  sqlite4ReleaseTempReg(pParse, regData);
  sqlite4ReleaseTempReg(pParse, regKey);
  sqlite4VdbeAddOp2(v, OP_Close, iSrc, 0);
  sqlite4VdbeAddOp2(v, OP_Close, iDest, 0);
  if( emptyDestTest ){
    sqlite4VdbeAddOp2(v, OP_Halt, SQLITE4_OK, 0);
    sqlite4VdbeJumpHere(v, emptyDestTest);
    sqlite4VdbeAddOp2(v, OP_Close, iDest, 0);
    return 0;
  }else{
    return 1;
  }
}
#endif /* SQLITE4_OMIT_XFER_OPT */
Changes to src/kv.c.
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  return rc;
}

/*
** Store schema cookie value iVal.
*/
int sqlite4KVStorePutSchema(KVStore *p, unsigned int iVal){
  kvTrace(p, "xPutMeta(%d,%d)", p->kvId, (int)iVal);
  return p->pStoreVfunc->xPutMeta(p, iVal);
}

/*
** Read the schema cookie value into *piVal.
*/
int sqlite4KVStoreGetSchema(KVStore *p, unsigned int *piVal){







|







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  return rc;
}

/*
** Store schema cookie value iVal.
*/
int sqlite4KVStorePutSchema(KVStore *p, unsigned int iVal){
  kvTrace(p, "xPutMeta(%d,%d) -> %s", p->kvId, (int)iVal);
  return p->pStoreVfunc->xPutMeta(p, iVal);
}

/*
** Read the schema cookie value into *piVal.
*/
int sqlite4KVStoreGetSchema(KVStore *p, unsigned int *piVal){
Changes to src/lsmInt.h.
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
void lsmDbDatabaseRelease(lsm_db *);

int lsmBeginReadTrans(lsm_db *);
int lsmBeginWriteTrans(lsm_db *);
int lsmBeginFlush(lsm_db *);

int lsmDetectRoTrans(lsm_db *db, int *);
int lsmBeginRoTrans(lsm_db *db);

int lsmBeginWork(lsm_db *);
void lsmFinishWork(lsm_db *, int, int *);

int lsmFinishRecovery(lsm_db *);
void lsmFinishReadTrans(lsm_db *);
int lsmFinishWriteTrans(lsm_db *, int);







<







869
870
871
872
873
874
875

876
877
878
879
880
881
882
void lsmDbDatabaseRelease(lsm_db *);

int lsmBeginReadTrans(lsm_db *);
int lsmBeginWriteTrans(lsm_db *);
int lsmBeginFlush(lsm_db *);

int lsmDetectRoTrans(lsm_db *db, int *);


int lsmBeginWork(lsm_db *);
void lsmFinishWork(lsm_db *, int, int *);

int lsmFinishRecovery(lsm_db *);
void lsmFinishReadTrans(lsm_db *);
int lsmFinishWriteTrans(lsm_db *, int);
Changes to src/lsm_ckpt.c.
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237

}

/*
** Set the output variable to the number of KB of data written into the
** database file since the most recent checkpoint.
*/
int lsmCheckpointSize(lsm_db *db, int *pnKB){

  int rc = LSM_OK;
  u32 nSynced;

  /* Set nSynced to the number of pages that had been written when the 
  ** database was last checkpointed. */
  rc = lsmCheckpointSynced(db, 0, 0, &nSynced);

  if( rc==LSM_OK ){
    u32 nPgsz = db->pShmhdr->aSnap1[CKPT_HDR_PGSZ];
    u32 nWrite = db->pShmhdr->aSnap1[CKPT_HDR_NWRITE];
    *pnKB = (int)(( ((i64)(nWrite - nSynced) * nPgsz) + 1023) / 1024);
  }

  return rc;
}








>















>
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
}

/*
** Set the output variable to the number of KB of data written into the
** database file since the most recent checkpoint.
*/
int lsmCheckpointSize(lsm_db *db, int *pnKB){
  ShmHeader *pShm = db->pShmhdr;
  int rc = LSM_OK;
  u32 nSynced;

  /* Set nSynced to the number of pages that had been written when the 
  ** database was last checkpointed. */
  rc = lsmCheckpointSynced(db, 0, 0, &nSynced);

  if( rc==LSM_OK ){
    u32 nPgsz = db->pShmhdr->aSnap1[CKPT_HDR_PGSZ];
    u32 nWrite = db->pShmhdr->aSnap1[CKPT_HDR_NWRITE];
    *pnKB = (int)(( ((i64)(nWrite - nSynced) * nPgsz) + 1023) / 1024);
  }

  return rc;
}

Changes to src/lsm_file.c.
2381
2382
2383
2384
2385
2386
2387

2388
2389
2390
2391
2392
2393
2394
    const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
    int nSz = pFS->nPagesize;
    u8 *aBuf = 0;
    u8 *aData = 0;

    for(i=0; rc==LSM_OK && i<nPagePerBlock; i++){
      i64 iOff = iFromOff + i*nSz;


      /* Set aData to point to a buffer containing the from page */
      if( (iOff+nSz)<=pFS->nMapLimit ){
        u8 *aMap = (u8 *)(pFS->pMap);
        aData = &aMap[iOff];
      }else{
        if( aBuf==0 ){







>







2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
    const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
    int nSz = pFS->nPagesize;
    u8 *aBuf = 0;
    u8 *aData = 0;

    for(i=0; rc==LSM_OK && i<nPagePerBlock; i++){
      i64 iOff = iFromOff + i*nSz;
      Page *pPg;

      /* Set aData to point to a buffer containing the from page */
      if( (iOff+nSz)<=pFS->nMapLimit ){
        u8 *aMap = (u8 *)(pFS->pMap);
        aData = &aMap[iOff];
      }else{
        if( aBuf==0 ){
Changes to src/lsm_log.c.
1128
1129
1130
1131
1132
1133
1134


void lsmLogClose(lsm_db *db){
  if( db->pLogWriter ){
    lsmFree(db->pEnv, db->pLogWriter->buf.z);
    lsmFree(db->pEnv, db->pLogWriter);
    db->pLogWriter = 0;
  }
}









>
>
1128
1129
1130
1131
1132
1133
1134
1135
1136
void lsmLogClose(lsm_db *db){
  if( db->pLogWriter ){
    lsmFree(db->pEnv, db->pLogWriter->buf.z);
    lsmFree(db->pEnv, db->pLogWriter);
    db->pLogWriter = 0;
  }
}


Changes to src/lsm_main.c.
1003
1004
1005
1006
1007
1008
1009


    }else{
      lsm_rollback(pDb, 0);
    }
  }

  return rc;
}









>
>
1003
1004
1005
1006
1007
1008
1009
1010
1011
    }else{
      lsm_rollback(pDb, 0);
    }
  }

  return rc;
}


Changes to src/lsm_shared.c.
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
#ifdef LSM_LOG_WORK
      lsmLogMessage(pDb, 0, "finish checkpoint %d", 
          (int)lsmCheckpointId(pDb->aSnapshot, 0)
      );
#endif
    }

    if( rc==LSM_OK && bTruncate && nBlock>0 ){
      rc = lsmFsTruncateDb(pDb->pFS, (i64)nBlock*lsmFsBlockSize(pDb->pFS));
    }
  }

  lsmShmLock(pDb, LSM_LOCK_CHECKPOINTER, LSM_LOCK_UNLOCK, 0);
  if( pnWrite && rc==LSM_OK ) *pnWrite = nWrite;
  return rc;







|







954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
#ifdef LSM_LOG_WORK
      lsmLogMessage(pDb, 0, "finish checkpoint %d", 
          (int)lsmCheckpointId(pDb->aSnapshot, 0)
      );
#endif
    }

    if( rc==LSM_OK && bTruncate ){
      rc = lsmFsTruncateDb(pDb->pFS, (i64)nBlock*lsmFsBlockSize(pDb->pFS));
    }
  }

  lsmShmLock(pDb, LSM_LOCK_CHECKPOINTER, LSM_LOCK_UNLOCK, 0);
  if( pnWrite && rc==LSM_OK ) *pnWrite = nWrite;
  return rc;
1961
1962
1963
1964
1965
1966
1967

      nKB = (((i64)nWrite * lsmFsPageSize(pDb->pFS)) + 1023) / 1024;
    }
    *pnKB = nKB;
  }

  return rc;
}








>
1961
1962
1963
1964
1965
1966
1967
1968
      nKB = (((i64)nWrite * lsmFsPageSize(pDb->pFS)) + 1023) / 1024;
    }
    *pnKB = nKB;
  }

  return rc;
}

Changes to src/lsm_sorted.c.
1972
1973
1974
1975
1976
1977
1978



1979

1980
1981
1982
1983
1984
1985
1986
  int eType = 0;

  switch( iKey ){
    case CURSOR_DATA_TREE0:
    case CURSOR_DATA_TREE1: {
      TreeCursor *pTreeCsr = pCsr->apTreeCsr[iKey-CURSOR_DATA_TREE0];
      if( lsmTreeCursorValid(pTreeCsr) ){



        lsmTreeCursorKey(pTreeCsr, &eType, &pKey, &nKey);

      }
      break;
    }

    case CURSOR_DATA_SYSTEM: {
      Snapshot *pWorker = pCsr->pDb->pWorker;
      if( pWorker && (pCsr->flags & CURSOR_FLUSH_FREELIST) ){







>
>
>

>







1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
  int eType = 0;

  switch( iKey ){
    case CURSOR_DATA_TREE0:
    case CURSOR_DATA_TREE1: {
      TreeCursor *pTreeCsr = pCsr->apTreeCsr[iKey-CURSOR_DATA_TREE0];
      if( lsmTreeCursorValid(pTreeCsr) ){
        int nVal;
        void *pVal;

        lsmTreeCursorKey(pTreeCsr, &eType, &pKey, &nKey);
        lsmTreeCursorValue(pTreeCsr, &pVal, &nVal);
      }
      break;
    }

    case CURSOR_DATA_SYSTEM: {
      Snapshot *pWorker = pCsr->pDb->pWorker;
      if( pWorker && (pCsr->flags & CURSOR_FLUSH_FREELIST) ){
2367
2368
2369
2370
2371
2372
2373

2374
2375
2376
2377
2378
2379
2380
    pCsr->nPtr = iPtr;
  }
}

static int multiCursorAddAll(MultiCursor *pCsr, Snapshot *pSnap){
  Level *pLvl;
  int nPtr = 0;

  int rc = LSM_OK;

  for(pLvl=pSnap->pLevel; pLvl; pLvl=pLvl->pNext){
    /* If the LEVEL_INCOMPLETE flag is set, then this function is being
    ** called (indirectly) from within a sortedNewToplevel() call to
    ** construct pLvl. In this case ignore pLvl - this cursor is going to
    ** be used to retrieve a freelist entry from the LSM, and the partially







>







2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
    pCsr->nPtr = iPtr;
  }
}

static int multiCursorAddAll(MultiCursor *pCsr, Snapshot *pSnap){
  Level *pLvl;
  int nPtr = 0;
  int iPtr = 0;
  int rc = LSM_OK;

  for(pLvl=pSnap->pLevel; pLvl; pLvl=pLvl->pNext){
    /* If the LEVEL_INCOMPLETE flag is set, then this function is being
    ** called (indirectly) from within a sortedNewToplevel() call to
    ** construct pLvl. In this case ignore pLvl - this cursor is going to
    ** be used to retrieve a freelist entry from the LSM, and the partially
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
    void *pKey;
    int nKey;
    multiCursorGetKey(pCsr, pCsr->aTree[1], &pCsr->eType, &pKey, &nKey);
    *pRc = sortedBlobSet(pCsr->pDb->pEnv, &pCsr->key, pKey, nKey);
  }
}

#ifdef LSM_DEBUG_EXPENSIVE
static void assertCursorTree(MultiCursor *pCsr){
  int bRev = !!(pCsr->flags & CURSOR_PREV_OK);
  int *aSave = pCsr->aTree;
  int nSave = pCsr->nTree;
  int rc;

  pCsr->aTree = 0;







|







2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
    void *pKey;
    int nKey;
    multiCursorGetKey(pCsr, pCsr->aTree[1], &pCsr->eType, &pKey, &nKey);
    *pRc = sortedBlobSet(pCsr->pDb->pEnv, &pCsr->key, pKey, nKey);
  }
}

#ifndef NDEBUG
static void assertCursorTree(MultiCursor *pCsr){
  int bRev = !!(pCsr->flags & CURSOR_PREV_OK);
  int *aSave = pCsr->aTree;
  int nSave = pCsr->nTree;
  int rc;

  pCsr->aTree = 0;
3679
3680
3681
3682
3683
3684
3685

3686





3687
3688
3689
3690
3691
3692
3693
*/
static int mergeWorkerPushHierarchy(
  MergeWorker *pMW,               /* Merge worker object */
  int iTopic,                     /* Topic value for this key */
  void *pKey,                     /* Pointer to key buffer */
  int nKey                        /* Size of pKey buffer in bytes */
){

  int rc = LSM_OK;                /* Return Code */





  Pgno iPtr;                      /* Pointer value to accompany pKey/nKey */

  assert( pMW->aSave[0].bStore==0 );
  assert( pMW->aSave[1].bStore==0 );
  rc = mergeWorkerBtreeIndirect(pMW);

  /* Obtain the absolute pointer value to store along with the key in the







>

>
>
>
>
>







3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
*/
static int mergeWorkerPushHierarchy(
  MergeWorker *pMW,               /* Merge worker object */
  int iTopic,                     /* Topic value for this key */
  void *pKey,                     /* Pointer to key buffer */
  int nKey                        /* Size of pKey buffer in bytes */
){
  lsm_db *pDb = pMW->pDb;         /* Database handle */
  int rc = LSM_OK;                /* Return Code */
  int iLevel;                     /* Level of b-tree hierachy to write to */
  int nData;                      /* Size of aData[] in bytes */
  u8 *aData;                      /* Page data for level iLevel */
  int iOff;                       /* Offset on b-tree page to write record to */
  int nRec;                       /* Initial number of records on b-tree page */
  Pgno iPtr;                      /* Pointer value to accompany pKey/nKey */

  assert( pMW->aSave[0].bStore==0 );
  assert( pMW->aSave[1].bStore==0 );
  rc = mergeWorkerBtreeIndirect(pMW);

  /* Obtain the absolute pointer value to store along with the key in the
3812
3813
3814
3815
3816
3817
3818

3819
3820
3821
3822
3823
3824
3825
static int mergeWorkerNextPage(
  MergeWorker *pMW,               /* Merge worker object to append page to */
  Pgno iFPtr                      /* Pointer value for footer of new page */
){
  int rc = LSM_OK;                /* Return code */
  Page *pNext = 0;                /* New page appended to run */
  lsm_db *pDb = pMW->pDb;         /* Database handle */


  rc = lsmFsSortedAppend(pDb->pFS, pDb->pWorker, pMW->pLevel, 0, &pNext);
  assert( rc || pMW->pLevel->lhs.iFirst>0 || pMW->pDb->compress.xCompress );

  if( rc==LSM_OK ){
    u8 *aData;                    /* Data buffer belonging to page pNext */
    int nData;                    /* Size of aData[] in bytes */







>







3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
static int mergeWorkerNextPage(
  MergeWorker *pMW,               /* Merge worker object to append page to */
  Pgno iFPtr                      /* Pointer value for footer of new page */
){
  int rc = LSM_OK;                /* Return code */
  Page *pNext = 0;                /* New page appended to run */
  lsm_db *pDb = pMW->pDb;         /* Database handle */
  Segment *pSeg;                  /* Run to append to */

  rc = lsmFsSortedAppend(pDb->pFS, pDb->pWorker, pMW->pLevel, 0, &pNext);
  assert( rc || pMW->pLevel->lhs.iFirst>0 || pMW->pDb->compress.xCompress );

  if( rc==LSM_OK ){
    u8 *aData;                    /* Data buffer belonging to page pNext */
    int nData;                    /* Size of aData[] in bytes */
4042
4043
4044
4045
4046
4047
4048

4049
4050
4051
4052
4053
4054
4055
/*
** Free all resources allocated by mergeWorkerInit().
*/
static void mergeWorkerShutdown(MergeWorker *pMW, int *pRc){
  int i;                          /* Iterator variable */
  int rc = *pRc;
  MultiCursor *pCsr = pMW->pCsr;


  /* Unless the merge has finished, save the cursor position in the
  ** Merge.aInput[] array. See function mergeWorkerInit() for the 
  ** code to restore a cursor position based on aInput[].  */
  if( rc==LSM_OK && pCsr && lsmMCursorValid(pCsr) ){
    Merge *pMerge = pMW->pLevel->pMerge;
    int bBtree = (pCsr->pBtCsr!=0);







>







4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
/*
** Free all resources allocated by mergeWorkerInit().
*/
static void mergeWorkerShutdown(MergeWorker *pMW, int *pRc){
  int i;                          /* Iterator variable */
  int rc = *pRc;
  MultiCursor *pCsr = pMW->pCsr;
  Hierarchy *p = &pMW->hier;

  /* Unless the merge has finished, save the cursor position in the
  ** Merge.aInput[] array. See function mergeWorkerInit() for the 
  ** code to restore a cursor position based on aInput[].  */
  if( rc==LSM_OK && pCsr && lsmMCursorValid(pCsr) ){
    Merge *pMerge = pMW->pLevel->pMerge;
    int bBtree = (pCsr->pBtCsr!=0);
4177
4178
4179
4180
4181
4182
4183

4184
4185
4186
4187

4188
4189
4190
4191





4192
4193
4194
4195
4196
4197
4198

static int mergeWorkerStep(MergeWorker *pMW){
  lsm_db *pDb = pMW->pDb;       /* Database handle */
  MultiCursor *pCsr;            /* Cursor to read input data from */
  int rc = LSM_OK;              /* Return code */
  int eType;                    /* SORTED_SEPARATOR, WRITE or DELETE */
  void *pKey; int nKey;         /* Key */

  Pgno iPtr;
  int iVal;

  pCsr = pMW->pCsr;


  /* Pull the next record out of the source cursor. */
  lsmMCursorKey(pCsr, &pKey, &nKey);
  eType = pCsr->eType;






  /* Figure out if the output record may have a different pointer value
  ** than the previous. This is the case if the current key is identical to
  ** a key that appears in the lowest level run being merged. If so, set 
  ** iPtr to the absolute pointer value. If not, leave iPtr set to zero, 
  ** indicating that the output pointer value should be a copy of the pointer 
  ** value written with the previous key.  */







>




>




>
>
>
>
>







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

static int mergeWorkerStep(MergeWorker *pMW){
  lsm_db *pDb = pMW->pDb;       /* Database handle */
  MultiCursor *pCsr;            /* Cursor to read input data from */
  int rc = LSM_OK;              /* Return code */
  int eType;                    /* SORTED_SEPARATOR, WRITE or DELETE */
  void *pKey; int nKey;         /* Key */
  Segment *pSeg;                /* Output segment */
  Pgno iPtr;
  int iVal;

  pCsr = pMW->pCsr;
  pSeg = &pMW->pLevel->lhs;

  /* Pull the next record out of the source cursor. */
  lsmMCursorKey(pCsr, &pKey, &nKey);
  eType = pCsr->eType;

  if( eType & LSM_SYSTEMKEY ){
    int i;
    i = 1;
  }

  /* Figure out if the output record may have a different pointer value
  ** than the previous. This is the case if the current key is identical to
  ** a key that appears in the lowest level run being merged. If so, set 
  ** iPtr to the absolute pointer value. If not, leave iPtr set to zero, 
  ** indicating that the output pointer value should be a copy of the pointer 
  ** value written with the previous key.  */
Changes to src/lsm_tree.c.
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
  u32 nHeight;                    /* Height of tree structure */
};

#ifndef NDEBUG
/*
** assert() that a TreeKey.flags value is sane. Usage:
**
**   assert( lsmAssertFlagsOk(pTreeKey->flags) );
*/
static int lsmAssertFlagsOk(u8 keyflags){
  /* At least one flag must be set. Otherwise, what is this key doing? */
  assert( keyflags!=0 );

  /* The POINT_DELETE and INSERT flags cannot both be set. */
  assert( (keyflags & LSM_POINT_DELETE)==0 || (keyflags & LSM_INSERT)==0 );

  /* If both the START_DELETE and END_DELETE flags are set, then the INSERT
  ** flag must also be set. In other words - the three DELETE flags cannot
  ** all be set */
  assert( (keyflags & LSM_END_DELETE)==0 
       || (keyflags & LSM_START_DELETE)==0 
       || (keyflags & LSM_POINT_DELETE)==0 
  );

  return 1;
}

static int assert_delete_ranges_match(lsm_db *);
static int treeCountEntries(lsm_db *db);
#else
# define lsmAssertFlagsOk(x)
#endif

/*
** Container for a key-value pair. Within the *-shm file, each key/value
** pair is stored in a single allocation (which may not actually be 
** contiguous in memory). Layout is the TreeKey structure, followed by
** the nKey bytes of key blob, followed by the nValue bytes of value blob







|

|




















|







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
  u32 nHeight;                    /* Height of tree structure */
};

#ifndef NDEBUG
/*
** assert() that a TreeKey.flags value is sane. Usage:
**
**   assert( assertFlagsOk(pTreeKey->flags) );
*/
static int assertFlagsOk(u8 keyflags){
  /* At least one flag must be set. Otherwise, what is this key doing? */
  assert( keyflags!=0 );

  /* The POINT_DELETE and INSERT flags cannot both be set. */
  assert( (keyflags & LSM_POINT_DELETE)==0 || (keyflags & LSM_INSERT)==0 );

  /* If both the START_DELETE and END_DELETE flags are set, then the INSERT
  ** flag must also be set. In other words - the three DELETE flags cannot
  ** all be set */
  assert( (keyflags & LSM_END_DELETE)==0 
       || (keyflags & LSM_START_DELETE)==0 
       || (keyflags & LSM_POINT_DELETE)==0 
  );

  return 1;
}

static int assert_delete_ranges_match(lsm_db *);
static int treeCountEntries(lsm_db *db);
#else
# define assertFlagsOk(x)
#endif

/*
** Container for a key-value pair. Within the *-shm file, each key/value
** pair is stored in a single allocation (which may not actually be 
** contiguous in memory). Layout is the TreeKey structure, followed by
** the nKey bytes of key blob, followed by the nValue bytes of value blob
326
327
328
329
330
331
332

333
334
335
336
337
338
339
static void assertIsWorkingChild(
  lsm_db *db, 
  TreeNode *pNode, 
  TreeNode *pParent, 
  int iCell
){
  TreeNode *p;

  u32 iPtr = getChildPtr(pParent, WORKING_VERSION, iCell);
  p = treeShmptr(db, iPtr);
  assert( p==pNode );
}
#else
# define assertIsWorkingChild(w,x,y,z)
#endif







>







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
static void assertIsWorkingChild(
  lsm_db *db, 
  TreeNode *pNode, 
  TreeNode *pParent, 
  int iCell
){
  TreeNode *p;
  int rc = LSM_OK;
  u32 iPtr = getChildPtr(pParent, WORKING_VERSION, iCell);
  p = treeShmptr(db, iPtr);
  assert( p==pNode );
}
#else
# define assertIsWorkingChild(w,x,y,z)
#endif
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
*/
static TreeKey *csrGetKey(TreeCursor *pCsr, TreeBlob *pBlob, int *pRc){
  TreeKey *pRet;
  lsm_db *pDb = pCsr->pDb;
  u32 iPtr = pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[pCsr->aiCell[pCsr->iNode]];

  assert( iPtr );
  pRet = (TreeKey*)treeShmptrUnsafe(pDb, iPtr);
  if( !(pRet->flags & LSM_CONTIGUOUS) ){
    pRet = treeShmkey(pDb, iPtr, TKV_LOADVAL, pBlob, pRc);
  }

  return pRet;
}








|







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
*/
static TreeKey *csrGetKey(TreeCursor *pCsr, TreeBlob *pBlob, int *pRc){
  TreeKey *pRet;
  lsm_db *pDb = pCsr->pDb;
  u32 iPtr = pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[pCsr->aiCell[pCsr->iNode]];

  assert( iPtr );
  pRet = treeShmptrUnsafe(pDb, iPtr);
  if( !(pRet->flags & LSM_CONTIGUOUS) ){
    pRet = treeShmkey(pDb, iPtr, TKV_LOADVAL, pBlob, pRc);
  }

  return pRet;
}

1184
1185
1186
1187
1188
1189
1190

1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
** If either of the conditions are untrue, LSM_CORRUPT is returned. Or, if
** an error is encountered before the checks are completed, another LSM error
** code (i.e. LSM_IOERR or LSM_NOMEM) may be returned.
*/
static int treeCheckLinkedList(lsm_db *db){
  int rc = LSM_OK;
  int nVisit = 0;

  ShmChunk *p;

  p = treeShmChunkRc(db, db->treehdr.iFirst, &rc);

  while( rc==LSM_OK && p ){
    if( p->iNext ){
      if( p->iNext>=db->treehdr.nChunk ){
        rc = LSM_CORRUPT_BKPT;
      }else{
        ShmChunk *pNext = treeShmChunkRc(db, p->iNext, &rc);
        if( rc==LSM_OK ){







>



>







1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
** If either of the conditions are untrue, LSM_CORRUPT is returned. Or, if
** an error is encountered before the checks are completed, another LSM error
** code (i.e. LSM_IOERR or LSM_NOMEM) may be returned.
*/
static int treeCheckLinkedList(lsm_db *db){
  int rc = LSM_OK;
  int nVisit = 0;
  u32 iShmid;
  ShmChunk *p;

  p = treeShmChunkRc(db, db->treehdr.iFirst, &rc);
  iShmid = p->iShmid;
  while( rc==LSM_OK && p ){
    if( p->iNext ){
      if( p->iNext>=db->treehdr.nChunk ){
        rc = LSM_CORRUPT_BKPT;
      }else{
        ShmChunk *pNext = treeShmChunkRc(db, p->iNext, &rc);
        if( rc==LSM_OK ){
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404
      pCsr->iNode--;
      treeUpdatePtr(db, pCsr, iNew);
    }
  }
}

static int treeNextIsEndDelete(lsm_db *db, TreeCursor *pCsr){

  int iNode = pCsr->iNode;
  int iCell = pCsr->aiCell[iNode]+1;

  /* Cursor currently points to a leaf node. */
  assert( pCsr->iNode==(db->treehdr.root.nHeight-1) );

  while( iNode>=0 ){







>







1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
      pCsr->iNode--;
      treeUpdatePtr(db, pCsr, iNew);
    }
  }
}

static int treeNextIsEndDelete(lsm_db *db, TreeCursor *pCsr){
  TreeNode *pNode;
  int iNode = pCsr->iNode;
  int iCell = pCsr->aiCell[iNode]+1;

  /* Cursor currently points to a leaf node. */
  assert( pCsr->iNode==(db->treehdr.root.nHeight-1) );

  while( iNode>=0 ){
1413
1414
1415
1416
1417
1418
1419

1420
1421
1422
1423
1424
1425
1426
    iCell = pCsr->aiCell[iNode];
  }

  return 0;
}

static int treePrevIsStartDelete(lsm_db *db, TreeCursor *pCsr){

  int iNode = pCsr->iNode;

  /* Cursor currently points to a leaf node. */
  assert( pCsr->iNode==(db->treehdr.root.nHeight-1) );

  while( iNode>=0 ){
    TreeNode *pNode = pCsr->apTreeNode[iNode];







>







1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
    iCell = pCsr->aiCell[iNode];
  }

  return 0;
}

static int treePrevIsStartDelete(lsm_db *db, TreeCursor *pCsr){
  TreeNode *pNode;
  int iNode = pCsr->iNode;

  /* Cursor currently points to a leaf node. */
  assert( pCsr->iNode==(db->treehdr.root.nHeight-1) );

  while( iNode>=0 ){
    TreeNode *pNode = pCsr->apTreeNode[iNode];
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
      pNode = (TreeNode *)treeShmptrUnsafe(pDb, iNodePtr);
      iNode++;
      pCsr->apTreeNode[iNode] = pNode;

      /* Compare (pKey/nKey) with the key in the middle slot of B-tree node
      ** pNode. The middle slot is never empty. If the comparison is a match,
      ** then the search is finished. Break out of the loop. */
      pTreeKey = (TreeKey*)treeShmptrUnsafe(pDb, pNode->aiKeyPtr[1]);
      if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
        pTreeKey = treeShmkey(pDb, pNode->aiKeyPtr[1], TKV_LOADKEY, &b, &rc);
        if( rc!=LSM_OK ) break;
      }
      res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
      if( res==0 ){
        pCsr->aiCell[iNode] = 1;
        break;
      }

      /* Based on the results of the previous comparison, compare (pKey/nKey)
      ** to either the left or right key of the B-tree node, if such a key
      ** exists. */
      iTest = (res>0 ? 0 : 2);
      iTreeKey = pNode->aiKeyPtr[iTest];
      if( iTreeKey ){
        pTreeKey = (TreeKey*)treeShmptrUnsafe(pDb, iTreeKey);
        if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
          pTreeKey = treeShmkey(pDb, iTreeKey, TKV_LOADKEY, &b, &rc);
          if( rc ) break;
        }
        res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
        if( res==0 ){
          pCsr->aiCell[iNode] = iTest;







|
















|







2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
      pNode = (TreeNode *)treeShmptrUnsafe(pDb, iNodePtr);
      iNode++;
      pCsr->apTreeNode[iNode] = pNode;

      /* Compare (pKey/nKey) with the key in the middle slot of B-tree node
      ** pNode. The middle slot is never empty. If the comparison is a match,
      ** then the search is finished. Break out of the loop. */
      pTreeKey = treeShmptrUnsafe(pDb, pNode->aiKeyPtr[1]);
      if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
        pTreeKey = treeShmkey(pDb, pNode->aiKeyPtr[1], TKV_LOADKEY, &b, &rc);
        if( rc!=LSM_OK ) break;
      }
      res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
      if( res==0 ){
        pCsr->aiCell[iNode] = 1;
        break;
      }

      /* Based on the results of the previous comparison, compare (pKey/nKey)
      ** to either the left or right key of the B-tree node, if such a key
      ** exists. */
      iTest = (res>0 ? 0 : 2);
      iTreeKey = pNode->aiKeyPtr[iTest];
      if( iTreeKey ){
        pTreeKey = treeShmptrUnsafe(pDb, iTreeKey);
        if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
          pTreeKey = treeShmkey(pDb, iTreeKey, TKV_LOADKEY, &b, &rc);
          if( rc ) break;
        }
        res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
        if( res==0 ){
          pCsr->aiCell[iNode] = iTest;
Changes to src/main.c.
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709


































710
711
712
713
714
715
716
*/
void sqlite4_profile(
  sqlite4 *db,
  void *pArg,
  void (*xProfile)(void*,const char*,sqlite4_uint64),
  void (*xDestroy)(void*)
){

  sqlite4_mutex_enter(db->mutex);
  if( db->xProfileDestroy ){
    db->xProfileDestroy(db->pProfileArg);
  }
  db->xProfile = xProfile;
  db->xProfileDestroy = xDestroy;
  db->pProfileArg = pArg;
  sqlite4_mutex_leave(db->mutex);
}
#endif /* SQLITE4_OMIT_TRACE */



































/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite4_errmsg(sqlite4 *db){
  const char *z;







>










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







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
*/
void sqlite4_profile(
  sqlite4 *db,
  void *pArg,
  void (*xProfile)(void*,const char*,sqlite4_uint64),
  void (*xDestroy)(void*)
){
  void *pOld;
  sqlite4_mutex_enter(db->mutex);
  if( db->xProfileDestroy ){
    db->xProfileDestroy(db->pProfileArg);
  }
  db->xProfile = xProfile;
  db->xProfileDestroy = xDestroy;
  db->pProfileArg = pArg;
  sqlite4_mutex_leave(db->mutex);
}
#endif /* SQLITE4_OMIT_TRACE */

/*
** This function returns true if main-memory should be used instead of
** a temporary file for transient pager files and statement journals.
** The value returned depends on the value of db->temp_store (runtime
** parameter) and the compile time value of SQLITE4_TEMP_STORE. The
** following table describes the relationship between these two values
** and this functions return value.
**
**   SQLITE4_TEMP_STORE     db->temp_store     Location of temporary database
**   -----------------     --------------     ------------------------------
**   0                     any                file      (return 0)
**   1                     1                  file      (return 0)
**   1                     2                  memory    (return 1)
**   1                     0                  file      (return 0)
**   2                     1                  file      (return 0)
**   2                     2                  memory    (return 1)
**   2                     0                  memory    (return 1)
**   3                     any                memory    (return 1)
*/
int sqlite4TempInMemory(const sqlite4 *db){
#if SQLITE4_TEMP_STORE==1
  return ( db->temp_store==2 );
#endif
#if SQLITE4_TEMP_STORE==2
  return ( db->temp_store!=1 );
#endif
#if SQLITE4_TEMP_STORE==3
  return 1;
#endif
#if SQLITE4_TEMP_STORE<1 || SQLITE4_TEMP_STORE>3
  return 0;
#endif
}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite4_errmsg(sqlite4 *db){
  const char *z;
Changes to src/math.c.
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
}

/*
** Multiply two numbers and return the result.
*/
sqlite4_num sqlite4_num_mul(sqlite4_num A, sqlite4_num B){
  sqlite4_num r;

  if( A.e>SQLITE4_MX_EXP || B.e>SQLITE4_MX_EXP ){
    r.sign = A.sign ^ B.sign;
    r.m = (A.m && B.m) ? 1 : 0;

    r.e = SQLITE4_MX_EXP+1;
    r.approx = 0;
    return r;
  }
  if( A.m==0 ) return A;
  if( B.m==0 ) return B;
  while( A.m%10==0 ){ A.m /= 10; A.e++; }
  while( B.m%10==0 ){ B.m /= 10; B.e++; }
  r.sign = A.sign ^ B.sign;
  r.approx = A.approx | B.approx;







<
|
|
<
>
|
|
|







139
140
141
142
143
144
145

146
147

148
149
150
151
152
153
154
155
156
157
158
}

/*
** Multiply two numbers and return the result.
*/
sqlite4_num sqlite4_num_mul(sqlite4_num A, sqlite4_num B){
  sqlite4_num r;

  if( A.e>SQLITE4_MX_EXP ){
    A.sign ^= B.sign;

    return A;
  }else if( B.e>SQLITE4_MX_EXP ){
    B.sign ^= A.sign;
    return B;
  }
  if( A.m==0 ) return A;
  if( B.m==0 ) return B;
  while( A.m%10==0 ){ A.m /= 10; A.e++; }
  while( B.m%10==0 ){ B.m /= 10; B.e++; }
  r.sign = A.sign ^ B.sign;
  r.approx = A.approx | B.approx;
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
      return r;
    }
    return B;
  }
  if( B.m==0 ){
    r.sign = A.sign ^ B.sign;
    r.e = SQLITE4_NAN_EXP;
    r.m = 0;
    r.approx = 1;
    return r;
  }
  if( A.m==0 ){
    return A;
  }
  while( A.m<TENTH_MAX ){







|







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
      return r;
    }
    return B;
  }
  if( B.m==0 ){
    r.sign = A.sign ^ B.sign;
    r.e = SQLITE4_NAN_EXP;
    r.m = 1;
    r.approx = 1;
    return r;
  }
  if( A.m==0 ){
    return A;
  }
  while( A.m<TENTH_MAX ){
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
      nIn -= 1;
    }
  }
  
  /* If the IGNORE_WHITESPACE flag is set, ignore any leading whitespace. */
  i = 0;
  if( flags & SQLITE4_IGNORE_WHITESPACE ){
    while( i<nIn && sqlite4Isspace(zIn[i]) ) i+=incr;
  }
  if( nIn<=i ) return error_value;

  /* Check for a leading '+' or '-' symbol. */
  if( zIn[i]=='-' ){
    r.sign = 1;
    i += incr;







|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
      nIn -= 1;
    }
  }
  
  /* If the IGNORE_WHITESPACE flag is set, ignore any leading whitespace. */
  i = 0;
  if( flags & SQLITE4_IGNORE_WHITESPACE ){
    while( sqlite4Isspace(zIn[i]) && i<nIn ) i+=incr;
  }
  if( nIn<=i ) return error_value;

  /* Check for a leading '+' or '-' symbol. */
  if( zIn[i]=='-' ){
    r.sign = 1;
    i += incr;
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
      memcpy(z, "NaN", 4);
    }else{
      memcpy(z, "inf", 4);
    }
    return (z - zOut)+3;
  }
  if( x.m==0 ){
    if( bReal ){
      memcpy(z, "0.0", 4);
    }else{
      memcpy(z, "0", 2);
    }
    return 1+(z-zOut);
  }
  zNum = renderInt(x.m, zBuf, sizeof(zBuf));
  n = &zBuf[sizeof(zBuf)-1] - zNum;
  if( x.e>=0 && x.e+n<=25 ){
    /* Integer values with up to 25 digits */
    memcpy(z, zNum, n+1);







<
<
<
|
<







632
633
634
635
636
637
638



639

640
641
642
643
644
645
646
      memcpy(z, "NaN", 4);
    }else{
      memcpy(z, "inf", 4);
    }
    return (z - zOut)+3;
  }
  if( x.m==0 ){



    memcpy(z, "0", 2);

    return 1+(z-zOut);
  }
  zNum = renderInt(x.m, zBuf, sizeof(zBuf));
  n = &zBuf[sizeof(zBuf)-1] - zNum;
  if( x.e>=0 && x.e+n<=25 ){
    /* Integer values with up to 25 digits */
    memcpy(z, zNum, n+1);
720
721
722
723
724
725
726

727
728
729
730
  *z++ = 'e';
  if( x.e<0 ){
    *z++ = '-';
    x.e = -x.e;
  }else{
    *z++ = '+';
  }

  zNum = renderInt(x.e&0x7fff, zBuf, sizeof(zBuf));
  while( (z[0] = zNum[0])!=0 ){ z++; zNum++; }
  return (z-zOut);
}







>




715
716
717
718
719
720
721
722
723
724
725
726
  *z++ = 'e';
  if( x.e<0 ){
    *z++ = '-';
    x.e = -x.e;
  }else{
    *z++ = '+';
  }
  z++;
  zNum = renderInt(x.e&0x7fff, zBuf, sizeof(zBuf));
  while( (z[0] = zNum[0])!=0 ){ z++; zNum++; }
  return (z-zOut);
}
Changes to src/mem.c.
776
777
778
779
780
781
782


  return sqlite4_buffer_append(pBuf, p, n);
}

void sqlite4_buffer_clear(sqlite4_buffer *pBuf){
  sqlite4_mm_free(pBuf->pMM, pBuf->p);
  sqlite4_buffer_init(pBuf, pBuf->pMM);
}









>
>
776
777
778
779
780
781
782
783
784
  return sqlite4_buffer_append(pBuf, p, n);
}

void sqlite4_buffer_clear(sqlite4_buffer *pBuf){
  sqlite4_mm_free(pBuf->pMM, pBuf->p);
  sqlite4_buffer_init(pBuf, pBuf->pMM);
}


Changes to src/mutex_noop.c.
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
static int debugMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE4_OK; }

/*
** The sqlite4_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 
*/
static sqlite4_mutex *debugMutexAlloc(void *pX, int id){
  sqlite4_env *pEnv = (sqlite4_env*)pX;
  sqlite4DebugMutex *pNew = 0;
  pNew = sqlite4Malloc(pEnv, sizeof(*pNew));
  if( pNew ){
    pNew->id = id;
    pNew->cnt = 0;
    pNew->pEnv = pEnv;
  }







|
<







104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
static int debugMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE4_OK; }

/*
** The sqlite4_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 
*/
static sqlite4_mutex *debugMutexAlloc(sqlite4_env *pEnv, int id){

  sqlite4DebugMutex *pNew = 0;
  pNew = sqlite4Malloc(pEnv, sizeof(*pNew));
  if( pNew ){
    pNew->id = id;
    pNew->cnt = 0;
    pNew->pEnv = pEnv;
  }
Changes to src/parse.y.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
** One or more VALUES claues
*/
struct ValueList {
  ExprList *pList;
  Select *pSelect;
};

/*
** A COVERING clause.
*/
struct CoveringOpt { IdList *pList; Token sEnd; };

} // end %include

// Input is a single SQL command
input ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
ecmd ::= SEMI.







<
<
<
<
<







98
99
100
101
102
103
104





105
106
107
108
109
110
111
** One or more VALUES claues
*/
struct ValueList {
  ExprList *pList;
  Select *pSelect;
};






} // end %include

// Input is a single SQL command
input ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
ecmd ::= SEMI.
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
// 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,R,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







|







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// 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
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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,X,0,R,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);
}







|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
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);
}
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
  C.bIfnotexist = NE;
  C.tCreate = S;
  C.tName1 = X;
  C.tName2 = D;
  C.pTblName = sqlite4SrcListAppend(pParse->db, 0, &Y, 0);
}

cmd ::= createindex(C) LP idxlist(Z) RP(E) covering_opt(F). {
  Token *pEnd = (F.pList ? &F.sEnd : &E);
  sqlite4CreateIndex(pParse, &C, Z, F.pList, C.bUnique, pEnd, SQLITE4_SO_ASC,0);

}

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

%type idxlist {ExprList*}







|
<
|
>







1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
  C.bIfnotexist = NE;
  C.tCreate = S;
  C.tName1 = X;
  C.tName2 = D;
  C.pTblName = sqlite4SrcListAppend(pParse->db, 0, &Y, 0);
}

cmd ::= createindex(C) LP idxlist(Z) RP(E). {

  sqlite4CreateIndex(pParse, &C.tName1, &C.tName2, C.pTblName, Z, 
                C.bUnique, &C.tCreate, &E, SQLITE4_SO_ASC, C.bIfnotexist, 0);
}

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

%type idxlist {ExprList*}
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
  A = sqlite4ExprListAppend(pParse, 0, sqlite4PExpr(pParse, @Y, 0, 0, &Y));
  sqlite4ExprListSetName(pParse, A, &X, 1);
}
uidxlist(A) ::= ids(Y). {
  A = sqlite4ExprListAppend(pParse, 0, sqlite4PExpr(pParse, @Y, 0, 0, &Y));
}

%type covering_opt { struct CoveringOpt }
%destructor covering_opt {sqlite4IdListDelete(pParse->db, $$.pList);}
covering_opt(A) ::= . { A.pList = 0; }
covering_opt(A) ::= COVERING ALL(X). { 
  A.pList = sqlite4DbMallocZero(pParse->db, sizeof(IdList)); 
  A.sEnd = X;
}
covering_opt(A) ::= COVERING LP inscollist(X) RP(Y). { 
  A.pList = X; 
  A.sEnd = Y;
}


///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite4DropIndex(pParse, X, E);}

///////////////////////////// The PRAGMA command /////////////////////////////
//







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







1204
1205
1206
1207
1208
1209
1210












1211
1212
1213
1214
1215
1216
1217
  A = sqlite4ExprListAppend(pParse, 0, sqlite4PExpr(pParse, @Y, 0, 0, &Y));
  sqlite4ExprListSetName(pParse, A, &X, 1);
}
uidxlist(A) ::= ids(Y). {
  A = sqlite4ExprListAppend(pParse, 0, sqlite4PExpr(pParse, @Y, 0, 0, &Y));
}














///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite4DropIndex(pParse, X, E);}

///////////////////////////// The PRAGMA command /////////////////////////////
//
Changes to src/pragma.c.
238
239
240
241
242
243
244

245
246
247
248
249
250
251
    }else{
      goto pragma_out;
    }
  }

  pParse->nMem = 2;
  sqlite4VdbeRunOnlyOnce(v);

  zRight = 0;
  if( pList ){
    zRight = pList->a[0].zSpan;
    if( zRight==0 ){ 
      assert( pList->a[0].pExpr->op==TK_ID );
      zRight = pList->a[0].pExpr->u.zToken; 
    }







>







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    }else{
      goto pragma_out;
    }
  }

  pParse->nMem = 2;
  sqlite4VdbeRunOnlyOnce(v);
  if( pList && pList->nExpr>1 ) goto pragma_out;
  zRight = 0;
  if( pList ){
    zRight = pList->a[0].zSpan;
    if( zRight==0 ){ 
      assert( pList->a[0].pExpr->op==TK_ID );
      zRight = pList->a[0].pExpr->u.zToken; 
    }
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
           pCol->zType ? pCol->zType : "", 0);
        sqlite4VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
        if( pCol->zDflt ){
          sqlite4VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
        }else{
          sqlite4VdbeAddOp2(v, OP_Null, 0, 5);
        }
        sqlite4VdbeAddOp2(v, OP_Integer, pCol->iPrimKey, 6);
        sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 6);
      }
    }
  }else

  if( sqlite4_stricmp(zPragma, "index_info")==0 && zRight ){
    Index *pIdx;







|







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
           pCol->zType ? pCol->zType : "", 0);
        sqlite4VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
        if( pCol->zDflt ){
          sqlite4VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
        }else{
          sqlite4VdbeAddOp2(v, OP_Null, 0, 5);
        }
        sqlite4VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
        sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 6);
      }
    }
  }else

  if( sqlite4_stricmp(zPragma, "index_info")==0 && zRight ){
    Index *pIdx;
428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443


444
445
446
447
448
449
450
451
      }
    }
  }else

  if( sqlite4_stricmp(zPragma, "database_list")==0 ){
    int i;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    sqlite4VdbeSetNumCols(v, 2);
    pParse->nMem = 3;
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE4_STATIC);
    sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE4_STATIC);

    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pKV==0 ) continue;
      assert( db->aDb[i].zName!=0 );
      sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
      sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);


      sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 2);
    }
  }else

  if( sqlite4_stricmp(zPragma, "collation_list")==0 ){
    int i = 0;
    HashElem *p;
    sqlite4VdbeSetNumCols(v, 2);







|



>





>
>
|







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
      }
    }
  }else

  if( sqlite4_stricmp(zPragma, "database_list")==0 ){
    int i;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    sqlite4VdbeSetNumCols(v, 3);
    pParse->nMem = 3;
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE4_STATIC);
    sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE4_STATIC);
    sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE4_STATIC);
    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pKV==0 ) continue;
      assert( db->aDb[i].zName!=0 );
      sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
      sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
      sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0,
                           "filename", 0);
      sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
    }
  }else

  if( sqlite4_stricmp(zPragma, "collation_list")==0 ){
    int i = 0;
    HashElem *p;
    sqlite4VdbeSetNumCols(v, 2);
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
  **   PRAGMA kvdump
  **
  ** Print an ascii rendering of the complete content of the database file.
  */
  if( sqlite4_stricmp(zPragma, "kvdump")==0 ){
    sqlite4KVStoreDump(db->aDb[0].pKV);
  }else

  /*
  **   PRAGMA kvreplace(BLOB,BLOB)
  **
  ** Insert or replace a single raw record into the KV store.  This pragma
  ** is exceedingly dangerous and should not be used by general-purpose
  ** applications.  It is intended for internal testing only - to provide
  ** a convenient way to insert arbitrary content into the key/value store.
  */
  if( sqlite4_stricmp(zPragma, "kvreplace")==0
   && pList->nExpr==2
  ){
    int r1, r2;
    Vdbe *v = sqlite4GetVdbe(pParse);
    pParse->nTab = 1;
    pParse->nMem = 3;
    sqlite4BeginWriteOperation(pParse, 0, iDb);
    r1 = sqlite4ExprCodeTarget(pParse, pList->a[0].pExpr, 1);
    sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort,
                         r1, "key may not be null", P4_STATIC);
    sqlite4VdbeAddOp1(v, OP_ToBlob, r1);
    r2 = sqlite4ExprCodeTarget(pParse, pList->a[1].pExpr, 2);
    sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort,
                         r2, "value may not be null", P4_STATIC);
    sqlite4VdbeAddOp1(v, OP_ToBlob, r2);
    sqlite4VdbeAddOp0(v, OP_OpenWrite);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, r2, r1);
    sqlite4VdbeAddOp0(v, OP_Halt);
  }else
#endif /* SQLITE4_DEBUG

  /*
  **   PRAGMA integrity_check
  **
  ** Check that for each table, the content of any auxilliary indexes are 
  ** consistent with the primary key index.
  */
  if( sqlite4_stricmp(zPragma, "integrity_check")==0 ){







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







636
637
638
639
640
641
642





























643

644
645
646
647
648
649
650
  **   PRAGMA kvdump
  **
  ** Print an ascii rendering of the complete content of the database file.
  */
  if( sqlite4_stricmp(zPragma, "kvdump")==0 ){
    sqlite4KVStoreDump(db->aDb[0].pKV);
  }else





























#endif /* SQLITE4_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( sqlite4_stricmp(zPragma, "integrity_check")==0 ){
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
        Table *pTab = (Table *)sqliteHashData(x);
        int addrRewind;
        int nIdx = 0;
        int iPkCsr;
        Index *pPk;
        int iCsr;

        /* Do nothing for views or sqlite_kvstore */
        if( IsView(pTab) || IsKvstore(pTab) ) continue;

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







|
|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
        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==SQLITE4_INDEX_PRIMARYKEY ){
            pPk = pIdx;
            iPkCsr = nIdx+baseCsr;
          }
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
  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.
  */
  if( sqlite4_stricmp(zPragma, "shrink_memory")==0 ){
    sqlite4_db_release_memory(db);
  }else

  /*
  **  PRAGMA schema_version
  */
  if( sqlite4_stricmp(zPragma, "schema_version")==0 ){
    if( zRight ){
      /* Write the specified cookie value */
      static const VdbeOpList setCookie[] = {
        { OP_Transaction,    0,  1,  0},    /* 0 */
        { OP_Integer,        0,  1,  0},    /* 1 */
        { OP_SetCookie,      0,  0,  1},    /* 2 */
      };
      int addr = sqlite4VdbeAddOpList(v, ArraySize(setCookie), setCookie);
      sqlite4VdbeChangeP1(v, addr, iDb);
      sqlite4VdbeChangeP1(v, addr+1, sqlite4Atoi(zRight));
      sqlite4VdbeChangeP1(v, addr+2, iDb);
    }else{
      /* Read the specified cookie value */
      static const VdbeOpList readCookie[] = {
        { OP_Transaction,     0,  0,  0},    /* 0 */
        { OP_ReadCookie,      0,  1,  0},    /* 1 */
        { OP_ResultRow,       1,  1,  0}
      };
      int addr = sqlite4VdbeAddOpList(v, ArraySize(readCookie), readCookie);
      sqlite4VdbeChangeP1(v, addr, iDb);
      sqlite4VdbeChangeP1(v, addr+1, iDb);
      sqlite4VdbeSetNumCols(v, 1);
      sqlite4VdbeSetColName(v, 0, COLNAME_NAME, zPragma, SQLITE4_TRANSIENT);
    }
  }else

 
  {/* Empty ELSE clause */}



 pragma_out:
  sqlite4DbFree(db, zPragma);
  /* sqlite4DbFree(db, zRight); */
  sqlite4ExprListDelete(db, pList);
}






















































































































































































































































































































































































































































































































































































































































#endif /* SQLITE4_OMIT_PRAGMA */







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











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

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
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
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
  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.
  */
  if( sqlite4_stricmp(zPragma, "shrink_memory")==0 ){
    sqlite4_db_release_memory(db);
  }else































 
  {/* Empty ELSE clause */}



 pragma_out:
  sqlite4DbFree(db, zPragma);
  /* sqlite4DbFree(db, zRight); */
  sqlite4ExprListDelete(db, pList);
}

#if 0
/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
**
** The identifier might also be a string.  The value is a string, and
** identifier, or a number.  If minusFlag is true, then the value is
** a number that was preceded by a minus sign.
**
** If the left side is "database.id" then pId1 is the database name
** and pId2 is the id.  If the left side is just "id" then pId1 is the
** id and pId2 is any empty string.
*/
void sqlite4Pragma(
  Parse *pParse, 
  Token *pId1,        /* First part of [database.]id field */
  Token *pId2,        /* Second part of [database.]id field, or NULL */
  ExprList *pList     /* List of pragma arguments */
){
  char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
  char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
  const char *zDb = 0;   /* The database name */
  Token *pId;            /* Pointer to <id> token */
  int iDb;               /* Database index for <database> */
  sqlite4 *db = pParse->db;
  Db *pDb;
  Vdbe *v = pParse->pVdbe = sqlite4VdbeCreate(db);
  if( v==0 ) return;
  sqlite4VdbeRunOnlyOnce(v);
  pParse->nMem = 2;

  /* Interpret the [database.] part of the pragma statement. iDb is the
  ** index of the database this pragma is being applied to in db.aDb[]. */
  iDb = sqlite4TwoPartName(pParse, pId1, pId2, &pId);
  if( iDb<0 ) return;
  pDb = &db->aDb[iDb];

  /* If the temp database has been explicitly named as part of the 
  ** pragma, make sure it is open. 
  */
  if( iDb==1 && sqlite4OpenTempDatabase(pParse) ){
    return;
  }

  zLeft = sqlite4NameFromToken(db, pId);
  if( !zLeft ) return;
  if( minusFlag ){
    zRight = sqlite4MPrintf(db, "-%T", pValue);
  }else{
    zRight = sqlite4NameFromToken(db, pValue);
  }

  assert( pId2 );
  zDb = pId2->n>0 ? pDb->zName : 0;
  if( sqlite4AuthCheck(pParse, SQLITE4_PRAGMA, zLeft, zRight, zDb) ){
    goto pragma_out;
  }
 


#ifndef SQLITE4_OMIT_FLAG_PRAGMAS
  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() subroutine also generates any necessary code
    ** there is nothing more to do here */
  }else
#endif /* SQLITE4_OMIT_FLAG_PRAGMAS */

  /*
  **   PRAGMA fts_check(<index>)
  */
  if( sqlite4_stricmp(zLeft, "fts_check")==0 && zRight ){
    int iCksum1;
    int iCksum2;
    Index *pIdx;
    Table *pTab;
    Vdbe *v = sqlite4GetVdbe(pParse);
    if( v==0 || sqlite4ReadSchema(pParse) ) goto pragma_out;

    iCksum1 = ++pParse->nMem;
    iCksum2 = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, iCksum1);
    sqlite4VdbeAddOp2(v, OP_Integer, 0, iCksum2);

    pIdx = sqlite4FindIndex(db, zRight, zDb);
    if( pIdx && pIdx->eIndexType==SQLITE4_INDEX_FTS5 ){
      int iTab = pParse->nTab++;
      int iAddr;
      int iReg;
      int i;

      pTab = pIdx->pTable;
      sqlite4OpenPrimaryKey(pParse, iTab, iDb, pTab, OP_OpenRead);
      iAddr = sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);

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

      sqlite4VdbeAddOp2(v, OP_RowKey, iTab, iReg);
      for(i=0; i<pTab->nCol; i++){
        sqlite4VdbeAddOp3(v, OP_Column, iTab, i, iReg+1+i);
      }
      sqlite4Fts5CodeCksum(pParse, pIdx, iCksum1, iReg, 0);

      sqlite4VdbeAddOp2(v, OP_Next, iTab, iAddr+1);
      sqlite4VdbeJumpHere(v, iAddr);
      sqlite4VdbeAddOp1(v, OP_Close, iTab);

      sqlite4VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
      iAddr = sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);

      iReg = pParse->nMem+1;
      pParse->nMem += 2;
      sqlite4VdbeAddOp2(v, OP_RowKey, iTab, iReg);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, iReg+1);
      sqlite4Fts5CodeCksum(pParse, pIdx, iCksum2, iReg, 1);

      sqlite4VdbeAddOp2(v, OP_Next, iTab, iAddr+1);
      sqlite4VdbeJumpHere(v, iAddr);
      sqlite4VdbeAddOp1(v, OP_Close, iTab);

      iReg = ++pParse->nMem;
      sqlite4VdbeAddOp4(v, OP_String8, 0, iReg, 0, "ok", 0);
      iAddr = sqlite4VdbeAddOp3(v, OP_Eq, iCksum1, 0, iCksum2);
      sqlite4VdbeAddOp4(v, OP_String8, 0, iReg, 0, "error - cksum mismatch", 0);
      sqlite4VdbeJumpHere(v, iAddr);
      sqlite4VdbeAddOp2(v, OP_ResultRow, iReg, 1);

      sqlite4VdbeSetNumCols(v, 1);
    }
  }



#ifndef SQLITE4_OMIT_SCHEMA_PRAGMAS
  /*
  **   PRAGMA table_info(<table>)
  **
  ** Return a single row for each column of the named table. The columns of
  ** the returned data set are:
  **
  ** cid:        Column id (numbered from left to right, starting at 0)
  ** name:       Column name
  ** type:       Column declaration type.
  ** notnull:    True if 'NOT NULL' is part of column declaration
  ** dflt_value: The default value for the column, if any.
  */
  if( sqlite4_stricmp(zLeft, "table_info")==0 && zRight ){
    Table *pTab;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite4FindTable(db, zRight, zDb);
    if( pTab ){
      int i;
      int nHidden = 0;
      Column *pCol;
      sqlite4VdbeSetNumCols(v, 6);
      pParse->nMem = 6;
      sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE4_STATIC);
      sqlite4ViewGetColumnNames(pParse, pTab);
      for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
        if( IsHiddenColumn(pCol) ){
          nHidden++;
          continue;
        }
        sqlite4VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
        sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
        sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0,
           pCol->zType ? pCol->zType : "", 0);
        sqlite4VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
        if( pCol->zDflt ){
          sqlite4VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
        }else{
          sqlite4VdbeAddOp2(v, OP_Null, 0, 5);
        }
        sqlite4VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
        sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 6);
      }
    }
  }else

  if( sqlite4_stricmp(zLeft, "index_info")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    pIdx = sqlite4FindIndex(db, zRight, zDb);
    if( pIdx ){
      int i;
      pTab = pIdx->pTable;
      sqlite4VdbeSetNumCols(v, 3);
      pParse->nMem = 3;
      sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE4_STATIC);
      sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE4_STATIC);
      for(i=0; i<pIdx->nColumn; i++){
        int cnum = pIdx->aiColumn[i];
        sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
        sqlite4VdbeAddOp2(v, OP_Integer, cnum, 2);
        assert( pTab->nCol>cnum );
        sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
        sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
      }
    }
  }else

  if( sqlite4_stricmp(zLeft, "index_list")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite4FindTable(db, zRight, zDb);
    if( pTab ){
      v = sqlite4GetVdbe(pParse);
      pIdx = pTab->pIndex;
      if( pIdx ){
        int i = 0; 
        sqlite4VdbeSetNumCols(v, 3);
        pParse->nMem = 3;
        sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE4_STATIC);
        while(pIdx){
          sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
          sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
          sqlite4VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
          sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
          ++i;
          pIdx = pIdx->pNext;
        }
      }
    }
  }else

  if( sqlite4_stricmp(zLeft, "database_list")==0 ){
    int i;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    sqlite4VdbeSetNumCols(v, 3);
    pParse->nMem = 3;
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE4_STATIC);
    sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE4_STATIC);
    sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE4_STATIC);
    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pKV==0 ) continue;
      assert( db->aDb[i].zName!=0 );
      sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
      sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
      sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0,
                           "filename", 0);
      sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 3);
    }
  }else

  if( sqlite4_stricmp(zLeft, "collation_list")==0 ){
    int i = 0;
    HashElem *p;
    sqlite4VdbeSetNumCols(v, 2);
    pParse->nMem = 2;
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE4_STATIC);
    sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE4_STATIC);
    for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
      CollSeq *pColl = (CollSeq *)sqliteHashData(p);
      sqlite4VdbeAddOp2(v, OP_Integer, i++, 1);
      sqlite4VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
      sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 2);
    }
  }else
#endif /* SQLITE4_OMIT_SCHEMA_PRAGMAS */

#ifndef SQLITE4_OMIT_FOREIGN_KEY
  if( sqlite4_stricmp(zLeft, "foreign_key_list")==0 && zRight ){
    FKey *pFK;
    Table *pTab;
    if( sqlite4ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite4FindTable(db, zRight, zDb);
    if( pTab ){
      v = sqlite4GetVdbe(pParse);
      pFK = pTab->pFKey;
      if( pFK ){
        int i = 0; 
        sqlite4VdbeSetNumCols(v, 8);
        pParse->nMem = 8;
        sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE4_STATIC);
        sqlite4VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE4_STATIC);
        while(pFK){
          int j;
          for(j=0; j<pFK->nCol; j++){
            char *zCol = pFK->aCol[j].zCol;
            char *zOnDelete = (char *)actionName(pFK->aAction[0]);
            char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
            sqlite4VdbeAddOp2(v, OP_Integer, i, 1);
            sqlite4VdbeAddOp2(v, OP_Integer, j, 2);
            sqlite4VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
            sqlite4VdbeAddOp4(v, OP_String8, 0, 4, 0,
                              pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
            sqlite4VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
            sqlite4VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
            sqlite4VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
            sqlite4VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
            sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 8);
          }
          ++i;
          pFK = pFK->pNextFrom;
        }
      }
    }
  }else
#endif /* !defined(SQLITE4_OMIT_FOREIGN_KEY) */

#ifndef NDEBUG
  if( sqlite4_stricmp(zLeft, "parser_trace")==0 ){
    if( zRight ){
      if( sqlite4GetBoolean(zRight) ){
        sqlite4ParserTrace(stderr, "parser: ");
      }else{
        sqlite4ParserTrace(0, 0);
      }
    }
  }else
#endif

  /* Reinstall the LIKE and GLOB functions.  The variant of LIKE
  ** used will be case sensitive or not depending on the RHS.
  */
  if( sqlite4_stricmp(zLeft, "case_sensitive_like")==0 ){
    if( zRight ){
      sqlite4RegisterLikeFunctions(db, sqlite4GetBoolean(zRight));
    }
  }else

#ifndef SQLITE4_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE4_INTEGRITY_CHECK_ERROR_MAX 100
#endif


#ifndef SQLITE4_OMIT_UTF16
  /*
  **   PRAGMA encoding
  **   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
  **
  ** In its first form, this pragma returns the encoding of the main
  ** database. If the database is not initialized, it is initialized now.
  **
  ** The second form of this pragma is a no-op if the main database file
  ** has not already been initialized. In this case it sets the default
  ** encoding that will be used for the main database file if a new file
  ** is created. If an existing main database file is opened, then the
  ** default text encoding for the existing database is used.
  ** 
  ** In all cases new databases created using the ATTACH command are
  ** created to use the same default text encoding as the main database. If
  ** the main database has not been initialized and/or created when ATTACH
  ** is executed, this is done before the ATTACH operation.
  **
  ** In the second form this pragma sets the text encoding to be used in
  ** new database files created using this database handle. It is only
  ** useful if invoked immediately after the main database i
  */
  if( sqlite4_stricmp(zLeft, "encoding")==0 ){
    static const struct EncName {
      char *zName;
      u8 enc;
    } encnames[] = {
      { "UTF8",     SQLITE4_UTF8        },
      { "UTF-8",    SQLITE4_UTF8        },  /* Must be element [1] */
      { "UTF-16le", SQLITE4_UTF16LE     },  /* Must be element [2] */
      { "UTF-16be", SQLITE4_UTF16BE     },  /* Must be element [3] */
      { "UTF16le",  SQLITE4_UTF16LE     },
      { "UTF16be",  SQLITE4_UTF16BE     },
      { "UTF-16",   0                  }, /* SQLITE4_UTF16NATIVE */
      { "UTF16",    0                  }, /* SQLITE4_UTF16NATIVE */
      { 0, 0 }
    };
    const struct EncName *pEnc;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( sqlite4ReadSchema(pParse) ) goto pragma_out;
      sqlite4VdbeSetNumCols(v, 1);
      sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE4_STATIC);
      sqlite4VdbeAddOp2(v, OP_String8, 0, 1);
      assert( encnames[SQLITE4_UTF8].enc==SQLITE4_UTF8 );
      assert( encnames[SQLITE4_UTF16LE].enc==SQLITE4_UTF16LE );
      assert( encnames[SQLITE4_UTF16BE].enc==SQLITE4_UTF16BE );
      sqlite4VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
      sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 1);
    }else{                        /* "PRAGMA encoding = XXX" */
      /* Only change the value of sqlite.enc if the database handle is not
      ** initialized. If the main database exists, the new sqlite.enc value
      ** will be overwritten when the schema is next loaded. If it does not
      ** already exists, it will be created to use the new encoding value.
      */
      if( 
        !(DbHasProperty(db, 0, DB_SchemaLoaded)) || 
        DbHasProperty(db, 0, DB_Empty) 
      ){
        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
          if( 0==sqlite4_stricmp(zRight, pEnc->zName) ){
            ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE4_UTF16NATIVE;
            break;
          }
        }
        if( !pEnc->zName ){
          sqlite4ErrorMsg(pParse, "unsupported encoding: %s", zRight);
        }
      }
    }
  }else
#endif /* SQLITE4_OMIT_UTF16 */


#ifndef SQLITE4_OMIT_COMPILEOPTION_DIAGS
  /*
  **   PRAGMA compile_options
  **
  ** Return the names of all compile-time options used in this build,
  ** one option per row.
  */
  if( sqlite4_stricmp(zLeft, "compile_options")==0 ){
    int i = 0;
    const char *zOpt;
    sqlite4VdbeSetNumCols(v, 1);
    pParse->nMem = 1;
    sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE4_STATIC);
    while( (zOpt = sqlite4_compileoption_get(i++))!=0 ){
      sqlite4VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
      sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 1);
    }
  }else
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */

#ifdef SQLITE4_DEBUG
  /*
  **   PRAGMA kvdump
  **
  ** Print an ascii rendering of the complete content of the database file.
  */
  if( sqlite4_stricmp(zLeft, "kvdump")==0 ){
    sqlite4KVStoreDump(db->aDb[0].pKV);
  }else
#endif /* SQLITE4_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( sqlite4_stricmp(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==SQLITE4_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==SQLITE4_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, 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", SQLITE4_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.
  */
  if( sqlite4_stricmp(zLeft, "shrink_memory")==0 ){
    sqlite4_db_release_memory(db);
  }else

 
  {/* Empty ELSE clause */}
pragma_out:
  sqlite4DbFree(db, zLeft);
  sqlite4DbFree(db, zRight);
}
#endif

#endif /* SQLITE4_OMIT_PRAGMA */
Changes to src/prepare.c.
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
          sqlite4_value_text(apVal[2], 0)     /* Text of CREATE statement */
      );
    }
  }

  return 0;
}

static int createSchemaTable(
  InitData *pInit,
  const char *zName,
  i64 iRoot,
  const char *zSchema
){
  Table *pTab;
  initCallback(pInit, zName, iRoot, zSchema);
  if( pInit->rc ) return 1;
  pTab = sqlite4FindTable(pInit->db, zName, pInit->db->aDb[pInit->iDb].zName);
  if( ALWAYS(pTab) ) pTab->tabFlags |= TF_Readonly;
  return 0;
}


/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file.  The index of the
** database file is given by iDb.  iDb==0 is used for the main
** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE4_ error codes to
** indicate success or failure.
*/
static int sqlite4InitOne(sqlite4 *db, int iDb, char **pzErrMsg){
  int rc;
  Table *pTab;
  Db *pDb;
  InitData initData;
  char const *zMasterSchema;
  char const *zMasterName;
  char const *zKvstoreName;
  int openedTransaction = 0;




  static const char *aMaster[] = {
     "CREATE TABLE sqlite_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")", 

#ifndef SQLITE4_OMIT_TEMPDB

     "CREATE TEMP TABLE sqlite_temp_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"

#endif
  };
  static const char *aKvstore[] = {
     "CREATE TABLE sqlite_kvstore(key BLOB PRIMARY KEY, value BLOB)",
#ifndef SQLITE4_OMIT_TEMPDB
     "CREATE TABLE sqlite_temp_kvstore(key BLOB PRIMARY KEY, value BLOB)"
#endif
  };
  static const char *aKvstoreName[] = {
     "sqlite_kvstore",
#ifndef SQLITE4_OMIT_TEMPDB
     "sqlite_temp_kvstore"
#endif
  };


  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pSchema );
  assert( sqlite4_mutex_held(db->mutex) );



  /* zMasterName is the name of the master table.  */






  zMasterName = SCHEMA_TABLE(iDb);
  zKvstoreName = aKvstoreName[iDb==1];

  /* Construct the schema tables.  */
  initData.db = db;
  initData.iDb = iDb;
  initData.rc = SQLITE4_OK;
  initData.pzErrMsg = pzErrMsg;
  if( createSchemaTable(&initData, zMasterName, 1, aMaster[iDb==1])
   || createSchemaTable(&initData, zKvstoreName, KVSTORE_ROOT, aKvstore[iDb==1])
  ){
    rc = initData.rc;
    goto error_out;




  }

  /* Create a cursor to hold the database open
  */
  pDb = &db->aDb[iDb];
  if( pDb->pKV==0 ){
    if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){







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
















<


>
>
>
|






|
>

>







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

<
<





>
>
|
>
>
>
>
>
>

<






|
<
|


>
>
>
>







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
          sqlite4_value_text(apVal[2], 0)     /* Text of CREATE statement */
      );
    }
  }

  return 0;
}
















/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file.  The index of the
** database file is given by iDb.  iDb==0 is used for the main
** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE4_ error codes to
** indicate success or failure.
*/
static int sqlite4InitOne(sqlite4 *db, int iDb, char **pzErrMsg){
  int rc;
  Table *pTab;
  Db *pDb;
  InitData initData;
  char const *zMasterSchema;
  char const *zMasterName;

  int openedTransaction = 0;

  /*
  ** The master database table has a structure like this
  */
  static const char master_schema[] = 
     "CREATE TABLE sqlite_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;
#ifndef SQLITE4_OMIT_TEMPDB
  static const char temp_master_schema[] = 
     "CREATE TEMP TABLE sqlite_temp_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;
#else










  #define temp_master_schema 0
#endif



  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pSchema );
  assert( sqlite4_mutex_held(db->mutex) );

  /* zMasterSchema and zInitScript are set to point at the master schema
  ** and initialisation script appropriate for the database being
  ** initialised. zMasterName is the name of the master table.
  */
  if( !OMIT_TEMPDB && iDb==1 ){
    zMasterSchema = temp_master_schema;
  }else{
    zMasterSchema = master_schema;
  }
  zMasterName = SCHEMA_TABLE(iDb);


  /* Construct the schema tables.  */
  initData.db = db;
  initData.iDb = iDb;
  initData.rc = SQLITE4_OK;
  initData.pzErrMsg = pzErrMsg;
  initCallback(&initData, zMasterName, 1, zMasterSchema);

  if( initData.rc ){
    rc = initData.rc;
    goto error_out;
  }
  pTab = sqlite4FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( ALWAYS(pTab) ){
    pTab->tabFlags |= TF_Readonly;
  }

  /* Create a cursor to hold the database open
  */
  pDb = &db->aDb[iDb];
  if( pDb->pKV==0 ){
    if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
Changes to src/printf.c.
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
#define FLAG_STRING  4     /* Allow infinity precision */


/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
static const char aDigits[] = "0123456789abcdef0123456789ABCDEF";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    14, 0 },
  {  'z',  0, 4, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      0,  1 },
  {  'X', 16, 0, etRADIX,      16, 4 },
#ifndef SQLITE4_OMIT_FLOATING_POINT
  {  'f',  0, 1, etFLOAT,      0,  0 },
  {  'e',  0, 1, etEXP,        14, 0 },
  {  'E',  0, 1, etEXP,        30, 0 },
  {  'G',  0, 1, etGENERIC,    30, 0 },
#endif
  {  'i', 10, 1, etRADIX,      0,  0 },
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },

/* All the rest have the FLAG_INTERN bit set and are thus for internal







|




|







|
|


|
|
|







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
#define FLAG_STRING  4     /* Allow infinity precision */


/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 4, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      16, 1 },
  {  'X', 16, 0, etRADIX,      0,  4 },
#ifndef SQLITE4_OMIT_FLOATING_POINT
  {  'f',  0, 1, etFLOAT,      0,  0 },
  {  'e',  0, 1, etEXP,        30, 0 },
  {  'E',  0, 1, etEXP,        14, 0 },
  {  'G',  0, 1, etGENERIC,    14, 0 },
#endif
  {  'i', 10, 1, etRADIX,      0,  0 },
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },

/* All the rest have the FLAG_INTERN bit set and are thus for internal
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
void sqlite4XPrintf(StrAccum *p, const char *zFormat, ...){
  va_list ap;
  va_start(ap,zFormat);
  sqlite4VXPrintf(p, 1, zFormat, ap);
  va_end(ap);
}
#endif

/*
** Convert an N-byte blob into hex.  The caller is responsible for making
** sure zOut contains at least N*2+1 bytes of usable space.
*/
void sqlite4BlobToHex(int N, const u8 *zIn, char *zOut){
  while( (N--)>0 ){
    u8 c = *(zIn++);
    *(zOut++) = aDigits[c>>4];
    *(zOut++) = aDigits[c&0x0f];
  }
  *zOut = 0;
}







<
<
<
<
<
<
<
<
<
<
<
<
<
981
982
983
984
985
986
987













void sqlite4XPrintf(StrAccum *p, const char *zFormat, ...){
  va_list ap;
  va_start(ap,zFormat);
  sqlite4VXPrintf(p, 1, zFormat, ap);
  va_end(ap);
}
#endif













Changes to src/resolve.c.
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
  ** column number is greater than the number of bits in the bitmask
  ** then set the high-order bit of the bitmask.
  */
  if( pMatch!=0 ){
    int n = pExpr->iColumn;
    testcase( n==BMS-1 );
    if( n>=BMS || n<0 ){
      n = BMS-1;
    }
    assert( pMatch->iCursor==pExpr->iTable );
    pMatch->colUsed |= ((Bitmask)1)<<n;
  }

  /* Clean up and return







|


|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
  ** column number is greater than the number of bits in the bitmask
  ** then set the high-order bit of the bitmask.
  */
  if( pExpr->iColumn>=0 && pMatch!=0 ){
    int n = pExpr->iColumn;
    testcase( n==BMS-1 );
    if( n>=BMS ){
      n = BMS-1;
    }
    assert( pMatch->iCursor==pExpr->iTable );
    pMatch->colUsed |= ((Bitmask)1)<<n;
  }

  /* Clean up and return
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  if( p ){
    SrcListItem *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 || iCol<0) ? BMS-1 : iCol);
    ExprSetProperty(p, EP_Resolved);
  }
  return p;
}

static void resolveMatchArg(Parse *pParse, NameContext *pNC, Expr *pExpr){
  SrcList *pSrc = pNC->pSrcList;







|







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  if( p ){
    SrcListItem *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;
}

static void resolveMatchArg(Parse *pParse, NameContext *pNC, Expr *pExpr){
  SrcList *pSrc = pNC->pSrcList;
Changes to src/select.c.
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
  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);


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





  sqlite4VdbeAddOp3(v, OP_Insert, pOrderBy->iECursor, regData, regKey);

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

  if( pSelect->iLimit ){
    int addr1, addr2;







>
















>
>
>
>
>
|







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
  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;
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

  v = pParse->pVdbe;
  r1 = sqlite4GetTempReg(pParse);
  r2 = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
  sqlite4VdbeAddOp2(v, OP_MakeKey, iTab, r2);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
  sqlite4VdbeAddOp3(v, OP_Insert, iTab, r1, r2);
  sqlite4ReleaseTempReg(pParse, r1);
  sqlite4ReleaseTempReg(pParse, r2);
}

#ifndef SQLITE4_OMIT_SUBQUERY
/*
** Generate an error message when a SELECT is used within a subexpression







|







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

  v = pParse->pVdbe;
  r1 = sqlite4GetTempReg(pParse);
  r2 = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
  sqlite4VdbeAddOp2(v, OP_MakeKey, iTab, r2);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
  sqlite4VdbeAddOp3(v, OP_IdxInsert, iTab, r1, r2);
  sqlite4ReleaseTempReg(pParse, r1);
  sqlite4ReleaseTempReg(pParse, r2);
}

#ifndef SQLITE4_OMIT_SUBQUERY
/*
** Generate an error message when a SELECT is used within a subexpression
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
#ifndef SQLITE4_OMIT_COMPOUND_SELECT
    case SRT_Union: {
      int r1, r2;
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

    /* This is used for processing queries of the form:
    **







|







627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
#ifndef SQLITE4_OMIT_COMPOUND_SELECT
    case SRT_Union: {
      int r1, r2;
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      sqlite4VdbeAddOp3(v, OP_IdxInsert, iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

    /* This is used for processing queries of the form:
    **
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        pushOntoSorter(pParse, pOrderBy, p, r1);
      }else{
        int r2 = sqlite4GetTempReg(pParse);
        sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        sqlite4ExprCacheAffinityChange(pParse, regResult, 1);
        sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

    /* If any row exist in the result set, record that fact and abort.







|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        pushOntoSorter(pParse, pOrderBy, p, r1);
      }else{
        int r2 = sqlite4GetTempReg(pParse);
        sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        sqlite4ExprCacheAffinityChange(pParse, regResult, 1);
        sqlite4VdbeAddOp3(v, OP_IdxInsert, iParm, r1, r2);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

    /* If any row exist in the result set, record that fact and abort.
799
800
801
802
803
804
805


806
807
808
809
810
811
812
  pInfo = (KeyInfo *)sqlite4DbMallocZero(db, nByte);

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

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



    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;







>
>







805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  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;
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
  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 op;                         /* Opcode use to sort results */



  iTab = pOrderBy->iECursor;





  op = (p->selFlags & SF_UseSorter) ? OP_SorterSort : OP_Sort;









  addr = 1 + sqlite4VdbeAddOp2(v, op, iTab, addrBreak);
  codeOffset(v, p, addrContinue);


  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      int regRowid = sqlite4GetTempReg(pParse);
      int regRow = sqlite4GetTempReg(pParse);
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
      sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
      sqlite4ReleaseTempReg(pParse, regRow);
      sqlite4ReleaseTempReg(pParse, regRowid);
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case SRT_Set: {
      int regRes = sqlite4GetTempReg(pParse);
      int regKey = sqlite4GetTempReg(pParse);
      int regValue = sqlite4GetTempReg(pParse);
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRes);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, regKey);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, regRes, 1, regValue, &p->affinity, 1);

      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regValue, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);
      sqlite4ReleaseTempReg(pParse, regRes);
      sqlite4ReleaseTempReg(pParse, regValue);
      break;
    }
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, iParm);
      /* The LIMIT clause will terminate the loop for us */
      break;







>


|
>
>


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



<
<






<
<




<
<
<

|

|
>
|

<
<







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
  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, 0, regRow);
    sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE);
  }else{
    addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
    codeOffset(v, p, addrContinue);
    sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRow);
  }
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {


      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
      sqlite4VdbeChangeP5(v, OPFLAG_APPEND);


      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case SRT_Set: {



      assert( nColumn==1 );
      int regKey = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, regKey);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
      sqlite4ExprCacheAffinityChange(pParse, regRow, 1);
      sqlite4VdbeAddOp3(v, OP_IdxInsert, iParm, regRowid, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);


      break;
    }
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, iParm);
      /* The LIMIT clause will terminate the loop for us */
      break;
982
983
984
985
986
987
988


989
990
991
992
993
994
995
        sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
      break;
    }
  }



  /* The bottom of the loop
  */
  sqlite4VdbeResolveLabel(v, addrContinue);
  if( p->selFlags & SF_UseSorter ){
    sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
  }else{







>
>







1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
        sqlite4ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite4VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
      break;
    }
  }
  sqlite4ReleaseTempReg(pParse, regRow);
  sqlite4ReleaseTempReg(pParse, regRowid);

  /* The bottom of the loop
  */
  sqlite4VdbeResolveLabel(v, addrContinue);
  if( p->selFlags & SF_UseSorter ){
    sqlite4VdbeAddOp2(v, OP_SorterNext, iTab, addr);
  }else{
1866
1867
1868
1869
1870
1871
1872

1873
1874
1875
1876
1877
1878
1879
    pKeyInfo = sqlite4DbMallocZero(db,
                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE4_NOMEM;
      goto multi_select_end;
    }


    pKeyInfo->nField = (u16)nCol;

    for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
      *apColl = multiSelectCollSeq(pParse, p, i);
      if( 0==*apColl ){
        *apColl = db->pDfltColl;
      }







>







1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
    pKeyInfo = sqlite4DbMallocZero(db,
                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE4_NOMEM;
      goto multi_select_end;
    }

    pKeyInfo->enc = ENC(db);
    pKeyInfo->nField = (u16)nCol;

    for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
      *apColl = multiSelectCollSeq(pParse, p, i);
      if( 0==*apColl ){
        *apColl = db->pDfltColl;
      }
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
      p->affinity = 
         sqlite4CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, pDest->iParm, r2);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
      sqlite4ExprCacheAffinityChange(pParse, pIn->iMem, 1);
      sqlite4VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

#if 0  /* Never occurs on an ORDER BY query */
    /* If any row exist in the result set, record that fact and abort.







|







2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
      p->affinity = 
         sqlite4CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, pDest->iParm, r2);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
      sqlite4ExprCacheAffinityChange(pParse, pIn->iMem, 1);
      sqlite4VdbeAddOp3(v, OP_IdxInsert, pDest->iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

#if 0  /* Never occurs on an ORDER BY query */
    /* If any row exist in the result set, record that fact and abort.
2250
2251
2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
      aPermute[i] = pItem->iOrderByCol - 1;
    }
    pKeyMerge =
      sqlite4DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
    if( pKeyMerge ){
      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
      pKeyMerge->nField = (u16)nOrderBy;

      for(i=0; i<nOrderBy; i++){
        CollSeq *pColl;
        Expr *pTerm = pOrderBy->a[i].pExpr;
        if( pTerm->flags & EP_ExpCollate ){
          pColl = pTerm->pColl;
        }else{
          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);







>







2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
      aPermute[i] = pItem->iOrderByCol - 1;
    }
    pKeyMerge =
      sqlite4DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
    if( pKeyMerge ){
      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
      pKeyMerge->nField = (u16)nOrderBy;
      pKeyMerge->enc = ENC(db);
      for(i=0; i<nOrderBy; i++){
        CollSeq *pColl;
        Expr *pTerm = pOrderBy->a[i].pExpr;
        if( pTerm->flags & EP_ExpCollate ){
          pColl = pTerm->pColl;
        }else{
          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
2290
2291
2292
2293
2294
2295
2296

2297
2298
2299
2300
2301
2302
2303
    pParse->nMem += nExpr + 1;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regPrev);
    pKeyDup = sqlite4DbMallocZero(db,
                  sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
    if( pKeyDup ){
      pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
      pKeyDup->nField = (u16)nExpr;

      for(i=0; i<nExpr; i++){
        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
        pKeyDup->aSortOrder[i] = 0;
      }
    }
  }
 







>







2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
    pParse->nMem += nExpr + 1;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, regPrev);
    pKeyDup = sqlite4DbMallocZero(db,
                  sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
    if( pKeyDup ){
      pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
      pKeyDup->nField = (u16)nExpr;
      pKeyDup->enc = ENC(db);
      for(i=0; i<nExpr; i++){
        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
        pKeyDup->aSortOrder[i] = 0;
      }
    }
  }
 
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
  sqlite4VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
  sqlite4VdbeAddOp2(v, OP_If, regEofA, addrEofA);
  sqlite4VdbeAddOp2(v, OP_If, regEofB, addrEofB);

  /* Implement the main merge loop
  */
  sqlite4VdbeResolveLabel(v, labelCmpr);
  sqlite4VdbeAddOp4(v, OP_Permutation, nOrderBy, 0, 0,
                    (char*)aPermute, P4_INTARRAY);
  sqlite4VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  sqlite4VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);

  /* Jump to the this point in order to terminate the query.
  */
  sqlite4VdbeResolveLabel(v, labelEnd);







|
<







2482
2483
2484
2485
2486
2487
2488
2489

2490
2491
2492
2493
2494
2495
2496
  sqlite4VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
  sqlite4VdbeAddOp2(v, OP_If, regEofA, addrEofA);
  sqlite4VdbeAddOp2(v, OP_If, regEofB, addrEofB);

  /* Implement the main merge loop
  */
  sqlite4VdbeResolveLabel(v, labelCmpr);
  sqlite4VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);

  sqlite4VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  sqlite4VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);

  /* Jump to the this point in order to terminate the query.
  */
  sqlite4VdbeResolveLabel(v, labelEnd);
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
  }

  /* Aggregate and non-aggregate queries are handled differently */
  if( !isAgg && pGroupBy==0 ){
    ExprList *pDist = (isDistinct ? p->pEList : 0);

    /* Begin the database scan. */
    pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0, 0);
    if( pWInfo==0 ) goto select_end;
    if( sqlite4WhereOutputRowCount(pWInfo)<p->nSelectRow ){
      p->nSelectRow = sqlite4WhereOutputRowCount(pWInfo);
    }
    if( pOrderBy && sqlite4WhereIsOrdered(pWInfo) ) pOrderBy = 0;

    /* If sorting index that was created by a prior OP_OpenEphemeral 
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
    ** into an OP_Noop.
    */
    if( addrSortIndex>=0 && pOrderBy==0 ){
      sqlite4VdbeChangeToNoop(v, addrSortIndex);
      p->addrOpenEphm[2] = -1;
    }

    if( sqlite4WhereIsDistinct(pWInfo) ){
      VdbeOp *pOp;                /* No longer required OpenEphemeral instr. */
     
      assert( addrDistinctIndex>=0 );
      pOp = sqlite4VdbeGetOp(v, addrDistinctIndex);

      assert( isDistinct );
      assert( sqlite4WhereIsDistinct(pWInfo)==WHERE_DISTINCT_ORDERED 
           || sqlite4WhereIsDistinct(pWInfo)==WHERE_DISTINCT_UNIQUE 
      );
      distinct = -1;
      if( sqlite4WhereIsDistinct(pWInfo)==WHERE_DISTINCT_ORDERED ){
        int iJump;
        int iExpr;
        int iFlag = ++pParse->nMem;
        int iBase = pParse->nMem+1;
        int iBase2 = iBase + pEList->nExpr;
        pParse->nMem += (pEList->nExpr*2);








|

<
|
<
<










|






|
|


|







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
  }

  /* Aggregate and non-aggregate queries are handled differently */
  if( !isAgg && pGroupBy==0 ){
    ExprList *pDist = (isDistinct ? p->pEList : 0);

    /* Begin the database scan. */
    pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0);
    if( pWInfo==0 ) goto select_end;

    if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;



    /* If sorting index that was created by a prior OP_OpenEphemeral 
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
    ** into an OP_Noop.
    */
    if( addrSortIndex>=0 && pOrderBy==0 ){
      sqlite4VdbeChangeToNoop(v, addrSortIndex);
      p->addrOpenEphm[2] = -1;
    }

    if( pWInfo->eDistinct ){
      VdbeOp *pOp;                /* No longer required OpenEphemeral instr. */
     
      assert( addrDistinctIndex>=0 );
      pOp = sqlite4VdbeGetOp(v, addrDistinctIndex);

      assert( isDistinct );
      assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED 
           || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE 
      );
      distinct = -1;
      if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){
        int iJump;
        int iExpr;
        int iFlag = ++pParse->nMem;
        int iBase = pParse->nMem+1;
        int iBase2 = iBase + pEList->nExpr;
        pParse->nMem += (pEList->nExpr*2);

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
        sqlite4VdbeAddOp2(v, OP_If, iFlag, iJump-1);
        for(iExpr=0; iExpr<pEList->nExpr; iExpr++){
          CollSeq *pColl = sqlite4ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
          sqlite4VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
          sqlite4VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
          sqlite4VdbeChangeP5(v, SQLITE4_NULLEQ);
        }
        sqlite4VdbeAddOp2(v, OP_Goto, 0, sqlite4WhereContinueLabel(pWInfo));

        sqlite4VdbeAddOp2(v, OP_Integer, 0, iFlag);
        assert( sqlite4VdbeCurrentAddr(v)==iJump );
        sqlite4VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
      }else{
        pOp->opcode = OP_Noop;
      }
    }

    /* Use the standard inner loop. */
    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
        sqlite4WhereContinueLabel(pWInfo), sqlite4WhereBreakLabel(pWInfo)
    );

    /* End the database scan loop.
    */
    sqlite4WhereEnd(pWInfo);
  }else{
    /* This is the processing for aggregate queries */
    NameContext sNC;    /* Name context for processing aggregate information */







|











|
<







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
        sqlite4VdbeAddOp2(v, OP_If, iFlag, iJump-1);
        for(iExpr=0; iExpr<pEList->nExpr; iExpr++){
          CollSeq *pColl = sqlite4ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
          sqlite4VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
          sqlite4VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
          sqlite4VdbeChangeP5(v, SQLITE4_NULLEQ);
        }
        sqlite4VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue);

        sqlite4VdbeAddOp2(v, OP_Integer, 0, iFlag);
        assert( sqlite4VdbeCurrentAddr(v)==iJump );
        sqlite4VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
      }else{
        pOp->opcode = OP_Noop;
      }
    }

    /* Use the standard inner loop. */
    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
                    pWInfo->iContinue, pWInfo->iBreak);


    /* End the database scan loop.
    */
    sqlite4WhereEnd(pWInfo);
  }else{
    /* This is the processing for aggregate queries */
    NameContext sNC;    /* Name context for processing aggregate information */
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117

4118
4119
4120
4121
4122
4123
4124

      /* Begin a loop that will extract all source rows in GROUP BY order.
      ** This might involve two separate loops with an OP_Sort in between, or
      ** it might be a single loop that uses an index to extract information
      ** in the right order to begin with.
      */
      sqlite4VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
      if( pWInfo==0 ) goto select_end;
      if( sqlite4WhereIsOrdered(pWInfo) ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenEphemeral table will be
        ** cancelled later because we still need to use the pKeyInfo.
        */

        groupBySort = 0;

        /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
        ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
        ** Then compare the current GROUP BY terms against the GROUP BY terms
        ** from the previous row currently stored in a0, a1, a2...
        */







|

|


|

>







4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144

      /* Begin a loop that will extract all source rows in GROUP BY order.
      ** This might involve two separate loops with an OP_Sort in between, or
      ** it might be a single loop that uses an index to extract information
      ** in the right order to begin with.
      */
      sqlite4VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0);
      if( pWInfo==0 ) goto select_end;
      if( pGroupBy==0 ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenEphemeral table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        pGroupBy = p->pGroupBy;
        groupBySort = 0;

        /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
        ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
        ** Then compare the current GROUP BY terms against the GROUP BY terms
        ** from the previous row currently stored in a0, a1, a2...
        */
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
          sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
          sqlite4ReleaseTempRange(pParse, regBase, nCol);
        }

        /* Insert the key/value into the sorting index and end the loop
        ** generated by where.c code.  */
        sqlite4VdbeAddOp3(
            v, OP_Insert, sAggInfo.sortingIdx, regRecord, regKey
        );
        sqlite4WhereEnd(pWInfo);

        sqlite4VdbeAddOp2(v, OP_Null, 0, regKey);
        sqlite4VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort"));
        sAggInfo.useSortingIdx = 1;







|







4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
          sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
          sqlite4ReleaseTempRange(pParse, regBase, nCol);
        }

        /* Insert the key/value into the sorting index and end the loop
        ** generated by where.c code.  */
        sqlite4VdbeAddOp3(
            v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord, regKey
        );
        sqlite4WhereEnd(pWInfo);

        sqlite4VdbeAddOp2(v, OP_Null, 0, regKey);
        sqlite4VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort"));
        sAggInfo.useSortingIdx = 1;
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
        }
  
        /* This case runs if the aggregate has no GROUP BY clause.  The
        ** processing is much simpler since there is only a single row
        ** of output.
        */
        resetAccumulator(pParse, &sAggInfo);
        pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
        if( pWInfo==0 ){
          sqlite4ExprListDelete(db, pDel);
          goto select_end;
        }
        updateAccumulator(pParse, &sAggInfo);
        if( sqlite4WhereIsOrdered(pWInfo) && flag ){
          sqlite4VdbeAddOp2(v, OP_Goto, 0, sqlite4WhereBreakLabel(pWInfo));
          VdbeComment((v, "%s() by index",
                (flag==WHERE_ORDERBY_MIN?"min":"max")));
        }
        sqlite4WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, &sAggInfo);
      }








|





|
|







4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
        }
  
        /* This case runs if the aggregate has no GROUP BY clause.  The
        ** processing is much simpler since there is only a single row
        ** of output.
        */
        resetAccumulator(pParse, &sAggInfo);
        pWInfo = sqlite4WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag);
        if( pWInfo==0 ){
          sqlite4ExprListDelete(db, pDel);
          goto select_end;
        }
        updateAccumulator(pParse, &sAggInfo);
        if( !pMinMax && flag ){
          sqlite4VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
          VdbeComment((v, "%s() by index",
                (flag==WHERE_ORDERBY_MIN?"min":"max")));
        }
        sqlite4WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, &sAggInfo);
      }

Changes to src/sqlite.h.in.
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
#define SQLITE4_MISMATCH    20   /* Data type mismatch */
#define SQLITE4_MISUSE      21   /* Library used incorrectly */
#define SQLITE4_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE4_AUTH        23   /* Authorization denied */
#define SQLITE4_FORMAT      24   /* Auxiliary database format error */
#define SQLITE4_RANGE       25   /* 2nd param to sqlite4_bind out of range */
#define SQLITE4_NOTADB      26   /* File opened that is not a database file */
#define SQLITE4_NOTICE      27   /* Notifications from sqlite4_log() */
#define SQLITE4_WARNING     28   /* Warnings from sqlite4_log() */
#define SQLITE4_ROW         100  /* sqlite4_step() has another row ready */
#define SQLITE4_DONE        101  /* sqlite4_step() has finished executing */
#define SQLITE4_INEXACT     102  /* xSeek method of storage finds nearby ans */

/*
** CAPIREF: Extended Result Codes
** KEYWORDS: {extended error code} {extended error codes}







<
<







617
618
619
620
621
622
623


624
625
626
627
628
629
630
#define SQLITE4_MISMATCH    20   /* Data type mismatch */
#define SQLITE4_MISUSE      21   /* Library used incorrectly */
#define SQLITE4_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE4_AUTH        23   /* Authorization denied */
#define SQLITE4_FORMAT      24   /* Auxiliary database format error */
#define SQLITE4_RANGE       25   /* 2nd param to sqlite4_bind out of range */
#define SQLITE4_NOTADB      26   /* File opened that is not a database file */


#define SQLITE4_ROW         100  /* sqlite4_step() has another row ready */
#define SQLITE4_DONE        101  /* sqlite4_step() has finished executing */
#define SQLITE4_INEXACT     102  /* xSeek method of storage finds nearby ans */

/*
** CAPIREF: Extended Result Codes
** KEYWORDS: {extended error code} {extended error codes}
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
#define SQLITE4_IOERR_SEEK              (SQLITE4_IOERR | (22<<8))
#define SQLITE4_LOCKED_SHAREDCACHE      (SQLITE4_LOCKED |  (1<<8))
#define SQLITE4_BUSY_RECOVERY           (SQLITE4_BUSY   |  (1<<8))
#define SQLITE4_CANTOPEN_NOTEMPDIR      (SQLITE4_CANTOPEN | (1<<8))
#define SQLITE4_CORRUPT_VTAB            (SQLITE4_CORRUPT | (1<<8))
#define SQLITE4_READONLY_RECOVERY       (SQLITE4_READONLY | (1<<8))
#define SQLITE4_READONLY_CANTLOCK       (SQLITE4_READONLY | (2<<8))
#define SQLITE4_WARNING_AUTOINDEX       (SQLITE4_WARNING | (1<<8))

/*
** CAPIREF: Flags For File Open Operations
**
** These bit values are intended for use as options in the
** [sqlite4_open()] interface
*/







<







672
673
674
675
676
677
678

679
680
681
682
683
684
685
#define SQLITE4_IOERR_SEEK              (SQLITE4_IOERR | (22<<8))
#define SQLITE4_LOCKED_SHAREDCACHE      (SQLITE4_LOCKED |  (1<<8))
#define SQLITE4_BUSY_RECOVERY           (SQLITE4_BUSY   |  (1<<8))
#define SQLITE4_CANTOPEN_NOTEMPDIR      (SQLITE4_CANTOPEN | (1<<8))
#define SQLITE4_CORRUPT_VTAB            (SQLITE4_CORRUPT | (1<<8))
#define SQLITE4_READONLY_RECOVERY       (SQLITE4_READONLY | (1<<8))
#define SQLITE4_READONLY_CANTLOCK       (SQLITE4_READONLY | (2<<8))


/*
** CAPIREF: Flags For File Open Operations
**
** These bit values are intended for use as options in the
** [sqlite4_open()] interface
*/
Changes to src/sqliteInt.h.
13
14
15
16
17
18
19

20
21
22
23
24
25
26
**
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#define SQLITE4_OMIT_PROGRESS_CALLBACK 1
#define SQLITE4_OMIT_VIRTUALTABLE 1

#define SQLITE4_OMIT_LOCALTIME 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.
**







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
**
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#define SQLITE4_OMIT_PROGRESS_CALLBACK 1
#define SQLITE4_OMIT_VIRTUALTABLE 1
#define SQLITE4_OMIT_XFER_OPT 1
#define SQLITE4_OMIT_LOCALTIME 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.
**
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#include <ctype.h>    /* FIXME - can we omit this one? */

/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
#ifdef SQLITE4_OMIT_FLOATING_POINT
# define double sqlite4_int64







<







297
298
299
300
301
302
303

304
305
306
307
308
309
310
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>


/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
#ifdef SQLITE4_OMIT_FLOATING_POINT
# define double sqlite4_int64
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif

/* 
** Macros to compute minimum and maximum of two numbers.
*/
#define MIN(A,B) ((A)<(B)?(A):(B))
#define MAX(A,B) ((A)>(B)?(A):(B))

/*
** Check to see if this machine uses EBCDIC.  (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
#if 'A' == '\301'
# define SQLITE4_EBCDIC 1
#else







<
<
<
<
<
<







345
346
347
348
349
350
351






352
353
354
355
356
357
358
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif







/*
** Check to see if this machine uses EBCDIC.  (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
#if 'A' == '\301'
# define SQLITE4_EBCDIC 1
#else
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
#define MASTER_NAME       "sqlite_master"
#define TEMP_MASTER_NAME  "sqlite_temp_master"

/*
** The root-page of the master database table.
*/
#define MASTER_ROOT       1
#define KVSTORE_ROOT      0x7fffffff

#define IsKvstore(pTab) ((pTab)->pIndex && (pTab)->pIndex->tnum==KVSTORE_ROOT)

/*
** The name of the schema table.
*/
#define SCHEMA_TABLE(x)  ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)

/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X)    ((int)(sizeof(X)/sizeof(X[0])))

/*
** Determine if the argument is a power of two
*/
#define IsPowerOfTwo(X) (((X)&((X)-1))==0)

/*
** The following macros are used to suppress compiler warnings and to
** make it clear to human readers when a function parameter is deliberately 
** left unused within the body of a function. This usually happens when
** a function is called via a function pointer. For example the 
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,







<
<
<












<
<
<
<
<







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
#define MASTER_NAME       "sqlite_master"
#define TEMP_MASTER_NAME  "sqlite_temp_master"

/*
** The root-page of the master database table.
*/
#define MASTER_ROOT       1




/*
** The name of the schema table.
*/
#define SCHEMA_TABLE(x)  ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)

/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X)    ((int)(sizeof(X)/sizeof(X[0])))






/*
** The following macros are used to suppress compiler warnings and to
** make it clear to human readers when a function parameter is deliberately 
** left unused within the body of a function. This usually happens when
** a function is called via a function pointer. For example the 
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,
609
610
611
612
613
614
615

616
617
618
619
620
621
622
typedef struct SrcListItem SrcListItem;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct Token Token;
typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;

typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WherePlan WherePlan;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;








>







595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
typedef struct SrcListItem SrcListItem;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct Token Token;
typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
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;

932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
#define SQLITE4_IndexCover     0x10     /* Disable index covering table */
#define SQLITE4_GroupByOrder   0x20     /* Disable GROUPBY cover of ORDERBY */
#define SQLITE4_FactorOutConst 0x40     /* Disable factoring out constants */
#define SQLITE4_IdxRealAsInt   0x80     /* Store REAL as INT in indices */
#define SQLITE4_DistinctOpt    0x80     /* DISTINCT using indexes */
#define SQLITE4_OptMask        0xff     /* Mask of all disablable opts */

/*
** Some new things pulled in from SQLite3 use these macros. todo: Replace
** them with working versions.
*/
#define OptimizationDisabled(db, mask)  0
#define OptimizationEnabled(db, mask)  1

/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE4_MAGIC_OPEN    0x4d06c919  /* Database is open */
#define SQLITE4_MAGIC_CLOSED  0x5f2246b4  /* Database is closed */







<
<
<
<
<
<
<







919
920
921
922
923
924
925







926
927
928
929
930
931
932
#define SQLITE4_IndexCover     0x10     /* Disable index covering table */
#define SQLITE4_GroupByOrder   0x20     /* Disable GROUPBY cover of ORDERBY */
#define SQLITE4_FactorOutConst 0x40     /* Disable factoring out constants */
#define SQLITE4_IdxRealAsInt   0x80     /* Store REAL as INT in indices */
#define SQLITE4_DistinctOpt    0x80     /* DISTINCT using indexes */
#define SQLITE4_OptMask        0xff     /* Mask of all disablable opts */








/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE4_MAGIC_OPEN    0x4d06c919  /* Database is open */
#define SQLITE4_MAGIC_CLOSED  0x5f2246b4  /* Database is closed */
1041
1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
*/
struct Column {
  char *zName;     /* Name of this column */
  Expr *pDflt;     /* Default value of this column */
  char *zDflt;     /* Original text of the default value */
  char *zType;     /* Data type for this column */
  char *zColl;     /* Collating sequence.  If NULL, use the default */
  u16 iPrimKey;    /* Index of in the primary key.  0 if not part of PK */
  u8 notNull;      /* True if there is a NOT NULL constraint */

  char affinity;   /* One of the SQLITE4_AFF_... values */
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  u8 isHidden;     /* True if this column is 'hidden' */
#endif
};

/*







<

>







1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1035
1036
*/
struct Column {
  char *zName;     /* Name of this column */
  Expr *pDflt;     /* Default value of this column */
  char *zDflt;     /* Original text of the default value */
  char *zType;     /* Data type for this column */
  char *zColl;     /* Collating sequence.  If NULL, use the default */

  u8 notNull;      /* True if there is a NOT NULL constraint */
  u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
  char affinity;   /* One of the SQLITE4_AFF_... values */
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  u8 isHidden;     /* True if this column is 'hidden' */
#endif
};

/*
1317
1318
1319
1320
1321
1322
1323


1324
1325
1326
1327
1328
1329
1330





























1331
1332
1333
1334
1335
1336
1337

/*
** An instance of the following structure describes an index key.  It 
** includes information such as sort order and collating sequence for
** each key, and the number of primary key fields appended to the end.
*/
struct KeyInfo {


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






























/*
** Each SQL index is represented in memory by an
** instance of the following structure.
**
** The columns of the table that are to be indexed are described
** by the aiColumn[] field of this structure.  For example, suppose
** we have the following table and index:







>
>







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







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

/*
** An instance of the following structure describes an index key.  It 
** includes information such as sort order and collating sequence for
** 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 SQLITE4_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
** values.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store
** the key of an index.  A blob encoding of a record is created by
** the OP_MakeRecord opcode of the VDBE and is disassembled by the
** OP_Column opcode.
**
** This structure holds a record that has already been disassembled
** into its constituent fields.
*/
struct UnpackedRecord {
  KeyInfo *pKeyInfo;  /* Collation and sort-order information */
  u16 nField;         /* Number of entries in apMem[] */
  u8 flags;           /* Boolean settings.  UNPACKED_... below */
  i64 rowid;          /* Used by UNPACKED_PREFIX_SEARCH */
  Mem *aMem;          /* Values */
};

/*
** Allowed values of UnpackedRecord.flags
*/
#define UNPACKED_INCRKEY       0x01  /* Make this key an epsilon larger */
#define UNPACKED_PREFIX_MATCH  0x02  /* A prefix match is considered OK */
#define UNPACKED_PREFIX_SEARCH 0x04  /* Ignore final (rowid) field */

/*
** Each SQL index is represented in memory by an
** instance of the following structure.
**
** The columns of the table that are to be indexed are described
** by the aiColumn[] field of this structure.  For example, suppose
** we have the following table and index:
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
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
  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 */
  int nCover;      /* Number of covering columns in this index */
  int *aiCover;    /* Which columns are covered by this index */
  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;   /* SQLITE4_INDEX_USER, UNIQUE or PRIMARYKEY */
  u8 fIndex;       /* One or more of the IDX_* flags below */
  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 SQLITE4_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
  Fts5Index *pFts; /* Fts5 data (or NULL if this is not an fts index) */

  unsigned bUnordered:1;   /* Use this index for == or IN queries only */
};

/* Index.eIndexType must be set to one of the following. */
#define SQLITE4_INDEX_USER       0 /* Index created by CREATE INDEX statement */
#define SQLITE4_INDEX_UNIQUE     1 /* Index created by UNIQUE constraint */
#define SQLITE4_INDEX_PRIMARYKEY 2 /* Index is the tables PRIMARY KEY */
#define SQLITE4_INDEX_FTS5       3 /* Index is an FTS5 index */







<
<

















<
<







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
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
  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;   /* SQLITE4_INDEX_USER, UNIQUE or PRIMARYKEY */
  u8 fIndex;       /* One or more of the IDX_* flags below */
  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 SQLITE4_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
  Fts5Index *pFts; /* Fts5 data (or NULL if this is not an fts index) */


};

/* Index.eIndexType must be set to one of the following. */
#define SQLITE4_INDEX_USER       0 /* Index created by CREATE INDEX statement */
#define SQLITE4_INDEX_UNIQUE     1 /* Index created by UNIQUE constraint */
#define SQLITE4_INDEX_PRIMARYKEY 2 /* Index is the tables PRIMARY KEY */
#define SQLITE4_INDEX_FTS5       3 /* Index is an FTS5 index */
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
**
** The jointype starts out showing the join type between the current table
** and the next table on the list.  The parser builds the list this way.
** But sqlite4SrcListShiftJoinType() later shifts the jointypes so that each
** jointype expresses the join between the table and the previous table.
**
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used, or
** if the table uses an implicit primary key and it is accessed.
*/
struct SrcList {
  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  SrcListItem a[1]; /* One entry for each identifier on the list */
};








|
<







1795
1796
1797
1798
1799
1800
1801
1802

1803
1804
1805
1806
1807
1808
1809
**
** The jointype starts out showing the join type between the current table
** and the next table on the list.  The parser builds the list this way.
** But sqlite4SrcListShiftJoinType() later shifts the jointypes so that each
** jointype expresses the join between the table and the previous table.
**
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.

*/
struct SrcList {
  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  SrcListItem a[1]; /* One entry for each identifier on the list */
};

1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
  union {
    Index *pIdx;                   /* Index when WHERE_INDEXED is true */
    struct WhereTerm *pTerm;       /* WHERE clause term for OR-search */
    sqlite4_index_info *pVtabIdx;  /* Virtual table index to use */
  } u;
};

#if 0
/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure.  This structure
** is intended to be private the the where.c module and should not be
** access or modified by other modules.
**
** The pIdxInfo field is used to help pick the best index on a







<







1840
1841
1842
1843
1844
1845
1846

1847
1848
1849
1850
1851
1852
1853
  union {
    Index *pIdx;                   /* Index when WHERE_INDEXED is true */
    struct WhereTerm *pTerm;       /* WHERE clause term for OR-search */
    sqlite4_index_info *pVtabIdx;  /* Virtual table index to use */
  } u;
};


/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure.  This structure
** is intended to be private the the where.c module and should not be
** access or modified by other modules.
**
** The pIdxInfo field is used to help pick the best index on a
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
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
  ** we need a place to cache virtual table index information for each
  ** virtual table in the FROM clause and the WhereLevel structure is
  ** a convenient place since there is one WhereLevel for each FROM clause
  ** element.
  */
  sqlite4_index_info *pIdxInfo;  /* Index info for n-th source table */
};
#endif

#if 0
/*
** Flags appropriate for the wctrlFlags parameter of sqlite4WhereBegin()
** and the WhereInfo.wctrlFlags member.
*/
#define WHERE_ORDERBY_NORMAL   0x0000 /* No-op */
#define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
#define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
#define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
#define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
#define WHERE_NO_AUTOINDEX     0x0020 /* Do not use an auto-index search */
#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
#define WHERE_AND_ONLY         0x0080 /* Don't use indices for OR terms */
#endif


/*
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
** and the WhereInfo.wctrlFlags member.
*/
#define WHERE_ORDERBY_NORMAL   0x0000 /* No-op */
#define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
#define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
#define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
#define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
#define WHERE_FORCE_TABLE      0x0020 /* Do not use an index-only search */
#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
#define WHERE_AND_ONLY         0x0080 /* Don't use indices for OR terms */
#define WHERE_GROUPBY          0x0100 /* pOrderBy is really a GROUP BY */
#define WHERE_DISTINCTBY       0x0200 /* pOrderby is really a DISTINCT clause */
#define WHERE_WANT_DISTINCT    0x0400 /* All output needs to be distinct */



/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
*/
#if 0
struct WhereInfo {
  Parse *pParse;       /* Parsing and code generating context */
  u16 wctrlFlags;      /* Flags originally passed to sqlite4WhereBegin() */
  u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
  u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;
  SrcList *pTabList;             /* List of tables in the join */
  int iTop;                      /* The very beginning of the WHERE loop */
  int iContinue;                 /* Jump here to continue with next record */
  int iBreak;                    /* Jump here to break out of the loop */
  int nLevel;                    /* Number of nested loop */
  struct WhereClause *pWC;       /* Decomposition of the WHERE clause */
  double savedNQueryLoop;        /* pParse->nQueryLoop outside the WHERE loop */
  double nRowOut;                /* Estimated number of output rows */
  WhereLevel a[1];               /* Information about each nest loop in WHERE */
};
#endif

#define WHERE_DISTINCT_NOOP      0
#define WHERE_DISTINCT_UNIQUE    1
#define WHERE_DISTINCT_ORDERED   2
#define WHERE_DISTINCT_UNORDERED 3

/*
** A NameContext defines a context in which to resolve table and column
** names.  The context consists of a list of tables (the pSrcList) field and
** a list of named expression (pEList).  The named expression list may
** be NULL.  The pSrc corresponds to the FROM clause of a SELECT or
** to the table being operated on by INSERT, UPDATE, or DELETE.  The







<

<













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








<
















<

|
|
<
<







1883
1884
1885
1886
1887
1888
1889

1890

1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903





















1904
1905
1906
1907
1908
1909
1910
1911

1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930


1931
1932
1933
1934
1935
1936
1937
  ** we need a place to cache virtual table index information for each
  ** virtual table in the FROM clause and the WhereLevel structure is
  ** a convenient place since there is one WhereLevel for each FROM clause
  ** element.
  */
  sqlite4_index_info *pIdxInfo;  /* Index info for n-th source table */
};



/*
** Flags appropriate for the wctrlFlags parameter of sqlite4WhereBegin()
** and the WhereInfo.wctrlFlags member.
*/
#define WHERE_ORDERBY_NORMAL   0x0000 /* No-op */
#define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
#define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
#define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
#define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
#define WHERE_NO_AUTOINDEX     0x0020 /* Do not use an auto-index search */
#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
#define WHERE_AND_ONLY         0x0080 /* Don't use indices for OR terms */






















/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
*/

struct WhereInfo {
  Parse *pParse;       /* Parsing and code generating context */
  u16 wctrlFlags;      /* Flags originally passed to sqlite4WhereBegin() */
  u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
  u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;
  SrcList *pTabList;             /* List of tables in the join */
  int iTop;                      /* The very beginning of the WHERE loop */
  int iContinue;                 /* Jump here to continue with next record */
  int iBreak;                    /* Jump here to break out of the loop */
  int nLevel;                    /* Number of nested loop */
  struct WhereClause *pWC;       /* Decomposition of the WHERE clause */
  double savedNQueryLoop;        /* pParse->nQueryLoop outside the WHERE loop */
  double nRowOut;                /* Estimated number of output rows */
  WhereLevel a[1];               /* Information about each nest loop in WHERE */
};


#define WHERE_DISTINCT_UNIQUE 1
#define WHERE_DISTINCT_ORDERED 2



/*
** A NameContext defines a context in which to resolve table and column
** names.  The context consists of a list of tables (the pSrcList) field and
** a list of named expression (pEList).  The named expression list may
** be NULL.  The pSrc corresponds to the FROM clause of a SELECT or
** to the table being operated on by INSERT, UPDATE, or DELETE.  The
2511
2512
2513
2514
2515
2516
2517








2518
2519
2520
2521
2522
2523
2524
** SQLITE4_ENABLE_FTS3 macro.  But to avoid confusion we also all
** the SQLITE4_ENABLE_FTS4 macro to serve as an alisse for SQLITE4_ENABLE_FTS3.
*/
#if defined(SQLITE4_ENABLE_FTS4) && !defined(SQLITE4_ENABLE_FTS3)
# define SQLITE4_ENABLE_FTS3
#endif










/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
** sqlite versions only work for ASCII characters, regardless of locale.
*/
#ifdef SQLITE4_ASCII







>
>
>
>
>
>
>
>







2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
** SQLITE4_ENABLE_FTS3 macro.  But to avoid confusion we also all
** the SQLITE4_ENABLE_FTS4 macro to serve as an alisse for SQLITE4_ENABLE_FTS3.
*/
#if defined(SQLITE4_ENABLE_FTS4) && !defined(SQLITE4_ENABLE_FTS3)
# define SQLITE4_ENABLE_FTS3
#endif

/*
** The ctype.h header is needed for non-ASCII systems.  It is also
** needed by FTS3 when FTS3 is included in the amalgamation.
*/
#if !defined(SQLITE4_ASCII) || \
    (defined(SQLITE4_ENABLE_FTS3) && defined(SQLITE4_AMALGAMATION))
# include <ctype.h>
#endif

/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
** sqlite versions only work for ASCII characters, regardless of locale.
*/
#ifdef SQLITE4_ASCII
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
  int sqlite4IsNaN(double);
  int sqlite4IsInf(double);
#else
# define sqlite4IsNaN(X)  0
# define sqlite4IsInf(X)  0
#endif

void sqlite4BlobToHex(int, const u8*, char*);
void sqlite4VXPrintf(StrAccum*, int, const char*, va_list);
#ifndef SQLITE4_OMIT_TRACE
void sqlite4XPrintf(StrAccum*, const char*, ...);
#endif
char *sqlite4MPrintf(sqlite4*,const char*, ...);
char *sqlite4VMPrintf(sqlite4*,const char*, va_list);
char *sqlite4MAppendf(sqlite4*,char*,const char*,...);







<







2588
2589
2590
2591
2592
2593
2594

2595
2596
2597
2598
2599
2600
2601
  int sqlite4IsNaN(double);
  int sqlite4IsInf(double);
#else
# define sqlite4IsNaN(X)  0
# define sqlite4IsInf(X)  0
#endif


void sqlite4VXPrintf(StrAccum*, int, const char*, va_list);
#ifndef SQLITE4_OMIT_TRACE
void sqlite4XPrintf(StrAccum*, const char*, ...);
#endif
char *sqlite4MPrintf(sqlite4*,const char*, ...);
char *sqlite4VMPrintf(sqlite4*,const char*, va_list);
char *sqlite4MAppendf(sqlite4*,char*,const char*,...);
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
                                      Token*, Select*, Expr*, IdList*);
void sqlite4SrcListIndexedBy(Parse *, SrcList *, Token *);
int sqlite4IndexedByLookup(Parse *, SrcListItem *);
void sqlite4SrcListShiftJoinType(SrcList*);
void sqlite4SrcListAssignCursors(Parse*, SrcList*);
void sqlite4IdListDelete(sqlite4*, IdList*);
void sqlite4SrcListDelete(sqlite4*, SrcList*);
Index *sqlite4CreateIndex(Parse*,CreateIndex*,ExprList*,IdList*,int,Token*,int,int);

void sqlite4DropIndex(Parse*, SrcList*, int);
int sqlite4Select(Parse*, Select*, SelectDest*);
Select *sqlite4SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,int,Expr*,Expr*);
void sqlite4SelectDelete(sqlite4*, Select*);
Table *sqlite4SrcListLookup(Parse*, SrcList*);
int sqlite4IsReadOnly(Parse*, Table*, int);
void sqlite4OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) \
    && !defined(SQLITE4_OMIT_SUBQUERY)
Expr *sqlite4LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
#endif
void sqlite4DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite4Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite4WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);

void sqlite4WhereEnd(WhereInfo*);
u64 sqlite4WhereOutputRowCount(WhereInfo*);
int sqlite4WhereIsDistinct(WhereInfo*);
int sqlite4WhereIsOrdered(WhereInfo*);
int sqlite4WhereContinueLabel(WhereInfo*);
int sqlite4WhereBreakLabel(WhereInfo*);
int sqlite4WhereOkOnePass(WhereInfo*);
int sqlite4ExprCodeGetColumn(Parse*, Table*, int, int, int);
void sqlite4ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite4ExprCodeMove(Parse*, int, int, int);
void sqlite4ExprCodeCopy(Parse*, int, int, int);
void sqlite4ExprCacheStore(Parse*, int, int, int);
void sqlite4ExprCachePush(Parse*);
void sqlite4ExprCachePop(Parse*, int);







|
>














|
<

<
<
<
<
<
<







2706
2707
2708
2709
2710
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
                                      Token*, Select*, Expr*, IdList*);
void sqlite4SrcListIndexedBy(Parse *, SrcList *, Token *);
int sqlite4IndexedByLookup(Parse *, SrcListItem *);
void sqlite4SrcListShiftJoinType(SrcList*);
void sqlite4SrcListAssignCursors(Parse*, SrcList*);
void sqlite4IdListDelete(sqlite4*, IdList*);
void sqlite4SrcListDelete(sqlite4*, SrcList*);
Index *sqlite4CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*, int, int, int);
void sqlite4DropIndex(Parse*, SrcList*, int);
int sqlite4Select(Parse*, Select*, SelectDest*);
Select *sqlite4SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,int,Expr*,Expr*);
void sqlite4SelectDelete(sqlite4*, Select*);
Table *sqlite4SrcListLookup(Parse*, SrcList*);
int sqlite4IsReadOnly(Parse*, Table*, int);
void sqlite4OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE4_ENABLE_UPDATE_DELETE_LIMIT) \
    && !defined(SQLITE4_OMIT_SUBQUERY)
Expr *sqlite4LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
#endif
void sqlite4DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite4Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite4WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16);

void sqlite4WhereEnd(WhereInfo*);






int sqlite4ExprCodeGetColumn(Parse*, Table*, int, int, int);
void sqlite4ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite4ExprCodeMove(Parse*, int, int, int);
void sqlite4ExprCodeCopy(Parse*, int, int, int);
void sqlite4ExprCacheStore(Parse*, int, int, int);
void sqlite4ExprCachePush(Parse*);
void sqlite4ExprCachePop(Parse*, int);
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
int sqlite4RunVacuum(char**, sqlite4*);
char *sqlite4NameFromToken(sqlite4*, Token*);
int sqlite4ExprCompare(Expr*, Expr*);
int sqlite4ExprListCompare(ExprList*, ExprList*);
void sqlite4ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite4ExprAnalyzeAggList(NameContext*,ExprList*);
Vdbe *sqlite4GetVdbe(Parse*);



void sqlite4CodeVerifySchema(Parse*, int);
void sqlite4CodeVerifyNamedSchema(Parse*, const char *zDb);
void sqlite4BeginTransaction(Parse*, int);
void sqlite4EndTransaction(Parse *, int);
void sqlite4Savepoint(Parse*, int, Token*);
void sqlite4CloseSavepoints(sqlite4 *);
int sqlite4ExprIsConstant(Expr*);
int sqlite4ExprIsConstantNotJoin(Expr*);
int sqlite4ExprIsConstantOrFunction(Expr*);
int sqlite4ExprIsInteger(Expr*, int*);
int sqlite4ExprCanBeNull(const Expr*);
void sqlite4ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
int sqlite4ExprNeedsNoAffinityChange(const Expr*, char);
void sqlite4GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
void sqlite4GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
void sqlite4EncodeIndexKey(Parse *, Index *, int, Index *, int, int, int);
void sqlite4EncodeIndexValue(Parse*, int, Index*, 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*);







>
>
>
















<







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
int sqlite4RunVacuum(char**, sqlite4*);
char *sqlite4NameFromToken(sqlite4*, Token*);
int sqlite4ExprCompare(Expr*, Expr*);
int sqlite4ExprListCompare(ExprList*, ExprList*);
void sqlite4ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite4ExprAnalyzeAggList(NameContext*,ExprList*);
Vdbe *sqlite4GetVdbe(Parse*);
void sqlite4PrngSaveState(void);
void sqlite4PrngRestoreState(void);
void sqlite4PrngResetState(void);
void sqlite4CodeVerifySchema(Parse*, int);
void sqlite4CodeVerifyNamedSchema(Parse*, const char *zDb);
void sqlite4BeginTransaction(Parse*, int);
void sqlite4EndTransaction(Parse *, int);
void sqlite4Savepoint(Parse*, int, Token*);
void sqlite4CloseSavepoints(sqlite4 *);
int sqlite4ExprIsConstant(Expr*);
int sqlite4ExprIsConstantNotJoin(Expr*);
int sqlite4ExprIsConstantOrFunction(Expr*);
int sqlite4ExprIsInteger(Expr*, int*);
int sqlite4ExprCanBeNull(const Expr*);
void sqlite4ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
int sqlite4ExprNeedsNoAffinityChange(const Expr*, char);
void sqlite4GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
void sqlite4GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
void sqlite4EncodeIndexKey(Parse *, Index *, int, Index *, 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*);
2880
2881
2882
2883
2884
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
void sqlite4Detach(Parse*, Expr*);
int sqlite4FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite4FixSrcList(DbFixer*, SrcList*);
int sqlite4FixSelect(DbFixer*, Select*);
int sqlite4FixExpr(DbFixer*, Expr*);
int sqlite4FixExprList(DbFixer*, ExprList*);
int sqlite4FixTriggerStep(DbFixer*, TriggerStep*);

int sqlite4GetInt32(const char *, int*);
int sqlite4Atoi(const char*);
int sqlite4Utf16ByteLen(const void *pData, int nChar);
int sqlite4Utf8CharLen(const char *pData, int nByte);
u32 sqlite4Utf8Read(const char*, const char**);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c
** file.  Code should use the MACRO forms below, as the Varint32 versions
** are coded to assume the single byte case is already handled (which 
** the MACRO form does).
*/
int sqlite4PutVarint(unsigned char*, u64);
int sqlite4PutVarint32(unsigned char*, u32);
u8 sqlite4GetVarint(const unsigned char *, u64 *);
int sqlite4GetVarint32(const unsigned char *, u32 *);
int sqlite4VarintLen(u64 v);
int sqlite4GetVarint64(const unsigned char*, int, sqlite4_uint64 *pResult);
int sqlite4PutVarint64(unsigned char*, sqlite4_uint64);

/*
** The header of a record consists of a sequence variable-length integers.
** These integers are almost always small and are encoded as a single byte.







>
















|







2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
void sqlite4Detach(Parse*, Expr*);
int sqlite4FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite4FixSrcList(DbFixer*, SrcList*);
int sqlite4FixSelect(DbFixer*, Select*);
int sqlite4FixExpr(DbFixer*, Expr*);
int sqlite4FixExprList(DbFixer*, ExprList*);
int sqlite4FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite4AtoF(const char *z, double*, int, u8);
int sqlite4GetInt32(const char *, int*);
int sqlite4Atoi(const char*);
int sqlite4Utf16ByteLen(const void *pData, int nChar);
int sqlite4Utf8CharLen(const char *pData, int nByte);
u32 sqlite4Utf8Read(const char*, const char**);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c
** file.  Code should use the MACRO forms below, as the Varint32 versions
** are coded to assume the single byte case is already handled (which 
** the MACRO form does).
*/
int sqlite4PutVarint(unsigned char*, u64);
int sqlite4PutVarint32(unsigned char*, u32);
u8 sqlite4GetVarint(const unsigned char *, u64 *);
u8 sqlite4GetVarint32(const unsigned char *, u32 *);
int sqlite4VarintLen(u64 v);
int sqlite4GetVarint64(const unsigned char*, int, sqlite4_uint64 *pResult);
int sqlite4PutVarint64(unsigned char*, sqlite4_uint64);

/*
** The header of a record consists of a sequence variable-length integers.
** These integers are almost always small and are encoded as a single byte.
2978
2979
2980
2981
2982
2983
2984

2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
extern const unsigned char sqlite4OpcodeProperty[];
extern const unsigned char sqlite4UpperToLower[];
extern const unsigned char sqlite4CtypeMap[];
extern const Token sqlite4IntTokens[];
extern struct sqlite4_env sqlite4DefaultEnv;
extern struct KVFactory sqlite4BuiltinFactory;
#endif

void sqlite4Reindex(Parse*, Token*, Token*);
void sqlite4AlterFunctions(sqlite4_env*);
void sqlite4AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite4GetToken(const unsigned char *, int *);
void sqlite4NestedParse(Parse*, const char*, ...);
void sqlite4ExpirePreparedStatements(sqlite4*);
int sqlite4CodeSubselect(Parse *, Expr *, int);
void sqlite4SelectPrep(Parse*, Select*, NameContext*);
int sqlite4ResolveExprNames(NameContext*, Expr*);
void sqlite4ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite4ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite4ColumnDefault(Vdbe *, Table *, int, int);
void sqlite4AlterFinishAddColumn(Parse *, Token *);
void sqlite4AlterBeginAddColumn(Parse *, SrcList *);







>






|







2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
extern const unsigned char sqlite4OpcodeProperty[];
extern const unsigned char sqlite4UpperToLower[];
extern const unsigned char sqlite4CtypeMap[];
extern const Token sqlite4IntTokens[];
extern struct sqlite4_env sqlite4DefaultEnv;
extern struct KVFactory sqlite4BuiltinFactory;
#endif
void sqlite4RootPageMoved(sqlite4*, int, int, int);
void sqlite4Reindex(Parse*, Token*, Token*);
void sqlite4AlterFunctions(sqlite4_env*);
void sqlite4AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite4GetToken(const unsigned char *, int *);
void sqlite4NestedParse(Parse*, const char*, ...);
void sqlite4ExpirePreparedStatements(sqlite4*);
int sqlite4CodeSubselect(Parse *, Expr *, int, int);
void sqlite4SelectPrep(Parse*, Select*, NameContext*);
int sqlite4ResolveExprNames(NameContext*, Expr*);
void sqlite4ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite4ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite4ColumnDefault(Vdbe *, Table *, int, int);
void sqlite4AlterFinishAddColumn(Parse *, Token *);
void sqlite4AlterBeginAddColumn(Parse *, SrcList *);
3037
3038
3039
3040
3041
3042
3043







3044
3045
3046
3047
3048
3049
3050
*/
void *sqlite4ParserAlloc(void*(*)(void*,size_t), void*);
void sqlite4ParserFree(void*, void(*)(void*,void*));
void sqlite4Parser(void*, int, Token, Parse*);
#ifdef YYTRACKMAXSTACKDEPTH
  int sqlite4ParserStackPeak(void*);
#endif








#ifdef SQLITE4_TEST
  int sqlite4Utf8To8(char*);
#endif

#ifdef SQLITE4_OMIT_VIRTUALTABLE
#  define sqlite4VtabClear(Y)







>
>
>
>
>
>
>







3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
*/
void *sqlite4ParserAlloc(void*(*)(void*,size_t), void*);
void sqlite4ParserFree(void*, void(*)(void*,void*));
void sqlite4Parser(void*, int, Token, Parse*);
#ifdef YYTRACKMAXSTACKDEPTH
  int sqlite4ParserStackPeak(void*);
#endif

void sqlite4AutoLoadExtensions(sqlite4*);
#ifndef SQLITE4_OMIT_LOAD_EXTENSION
  void sqlite4CloseExtensions(sqlite4*);
#else
# define sqlite4CloseExtensions(X)
#endif

#ifdef SQLITE4_TEST
  int sqlite4Utf8To8(char*);
#endif

#ifdef SQLITE4_OMIT_VIRTUALTABLE
#  define sqlite4VtabClear(Y)
3081
3082
3083
3084
3085
3086
3087




3088
3089
3090
3091
3092
3093
3094
FuncDef *sqlite4VtabOverloadFunction(sqlite4 *,FuncDef*, int nArg, Expr*);
void sqlite4InvalidFunction(sqlite4_context*,int,sqlite4_value**);
int sqlite4VdbeParameterIndex(Vdbe*, const char*, int);
int sqlite4TransferBindings(sqlite4_stmt *, sqlite4_stmt *);
int sqlite4Reprepare(Vdbe*);
void sqlite4ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite4BinaryCompareCollSeq(Parse *, Expr *, Expr *);





/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
** this case foreign keys are parsed, but no other functionality is 
** provided (enforcement of FK constraints requires the triggers sub-system).







>
>
>
>







3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
FuncDef *sqlite4VtabOverloadFunction(sqlite4 *,FuncDef*, int nArg, Expr*);
void sqlite4InvalidFunction(sqlite4_context*,int,sqlite4_value**);
int sqlite4VdbeParameterIndex(Vdbe*, const char*, int);
int sqlite4TransferBindings(sqlite4_stmt *, sqlite4_stmt *);
int sqlite4Reprepare(Vdbe*);
void sqlite4ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite4BinaryCompareCollSeq(Parse *, Expr *, Expr *);
int sqlite4TempInMemory(const sqlite4*);
const char *sqlite4JournalModename(int);
int sqlite4Checkpoint(sqlite4*, int, int, int*, int*);
int sqlite4WalDefaultHook(void*,sqlite4*,const char*,int);

/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
** this case foreign keys are parsed, but no other functionality is 
** provided (enforcement of FK constraints requires the triggers sub-system).
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
#else
  #define sqlite4BeginBenignMalloc(X)
  #define sqlite4EndBenignMalloc(X)
#endif

#define IN_INDEX_ROWID           1
#define IN_INDEX_EPH             2
#define IN_INDEX_INDEX_ASC       3
#define IN_INDEX_INDEX_DESC      4
int sqlite4FindInIndex(Parse *, Expr *, int*, int*);
Index *sqlite4FindExistingInIndex(Parse *, Expr *, int);


#if SQLITE4_MAX_EXPR_DEPTH>0
  void sqlite4ExprSetHeight(Parse *pParse, Expr *p);
  int sqlite4SelectExprHeight(Select *);
  int sqlite4ExprCheckHeight(Parse*, int);







|
<
|







3125
3126
3127
3128
3129
3130
3131
3132

3133
3134
3135
3136
3137
3138
3139
3140
#else
  #define sqlite4BeginBenignMalloc(X)
  #define sqlite4EndBenignMalloc(X)
#endif

#define IN_INDEX_ROWID           1
#define IN_INDEX_EPH             2
#define IN_INDEX_INDEX           3

int sqlite4FindInIndex(Parse *, Expr *, int*);
Index *sqlite4FindExistingInIndex(Parse *, Expr *, int);


#if SQLITE4_MAX_EXPR_DEPTH>0
  void sqlite4ExprSetHeight(Parse *pParse, Expr *p);
  int sqlite4SelectExprHeight(Select *);
  int sqlite4ExprCheckHeight(Parse*, int);
Changes to src/update.c.
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  **
  ** 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
  ** RowSet 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, regRowSet, regOldKey);
  pWInfo = sqlite4WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0);
  if( pWInfo==0 ) goto update_cleanup;
  okOnePass = sqlite4WhereOkOnePass(pWInfo);
  sqlite4VdbeAddOp2(v, OP_RowKey, iCur+iPk, regOldKey);
  if( !okOnePass ){
    sqlite4VdbeAddOp3(v, OP_RowSetAdd, regRowSet, 0, regOldKey);
  }
  sqlite4WhereEnd(pWInfo);

  /* Open every index that needs updating. If any index could potentially 







|

|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  **
  ** 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
  ** RowSet 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, regRowSet, 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 ){
    sqlite4VdbeAddOp3(v, OP_RowSetAdd, regRowSet, 0, regOldKey);
  }
  sqlite4WhereEnd(pWInfo);

  /* Open every index that needs updating. If any index could potentially 
Changes to src/utf.c.
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    ** character. Two bytes are required in the output buffer for the
    ** nul-terminator.  */
    if( n<0 ){
      u8 *z = (u8*)p;
      while( z[0] || z[1] ) z += 2;
      n = z - (u8*)p;
    }
    nReq = n * 2 + 2;
  }else{
    /* When converting from UTF-16, the maximum growth results from
    ** translating a 2-byte character to a 4-byte UTF-8 character.
    ** A single byte is required for the output string
    ** nul-terminator.  */
    if( n<0 ) n = sqlite4Strlen30(p);
    nReq = n * 2 + 1;







|







577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    ** character. Two bytes are required in the output buffer for the
    ** nul-terminator.  */
    if( n<0 ){
      u8 *z = (u8*)p;
      while( z[0] || z[1] ) z += 2;
      n = z - (u8*)p;
    }
    nReq = n * 2 + 1;
  }else{
    /* When converting from UTF-16, the maximum growth results from
    ** translating a 2-byte character to a 4-byte UTF-8 character.
    ** A single byte is required for the output string
    ** nul-terminator.  */
    if( n<0 ) n = sqlite4Strlen30(p);
    nReq = n * 2 + 1;
Changes to src/util.c.
376
377
378
379
380
381
382













































































































































































































































































































































































































383
384
385
386
387
388
389
** string is not an integer, just return 0.
*/
int sqlite4Atoi(const char *z){
  int x = 0;
  if( z ) sqlite4GetInt32(z, &x);
  return x;
}














































































































































































































































































































































































































/*
** Read or write a four-byte big-endian integer value.
*/
u32 sqlite4Get4byte(const u8 *p){
  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}







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







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
** string is not an integer, just return 0.
*/
int sqlite4Atoi(const char *z){
  int x = 0;
  if( z ) sqlite4GetInt32(z, &x);
  return x;
}

/*
** The variable-length integer encoding is as follows:
**
** KEY:
**         A = 0xxxxxxx    7 bits of data and one flag bit
**         B = 1xxxxxxx    7 bits of data and one flag bit
**         C = xxxxxxxx    8 bits of data
**
**  7 bits - A
** 14 bits - BA
** 21 bits - BBA
** 28 bits - BBBA
** 35 bits - BBBBA
** 42 bits - BBBBBA
** 49 bits - BBBBBBA
** 56 bits - BBBBBBBA
** 64 bits - BBBBBBBBC
*/

/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data write will be between 1 and 9 bytes.  The number
** of bytes written is returned.
**
** A variable-length integer consists of the lower 7 bits of each byte
** for all bytes that have the 8th bit set and one byte with the 8th
** bit clear.  Except, if we get to the 9th byte, it stores the full
** 8 bits and is the last byte.
*/
int sqlite4PutVarint(unsigned char *p, u64 v){
  int i, j, n;
  u8 buf[10];
  if( v & (((u64)0xff000000)<<32) ){
    p[8] = (u8)v;
    v >>= 8;
    for(i=7; i>=0; i--){
      p[i] = (u8)((v & 0x7f) | 0x80);
      v >>= 7;
    }
    return 9;
  }    
  n = 0;
  do{
    buf[n++] = (u8)((v & 0x7f) | 0x80);
    v >>= 7;
  }while( v!=0 );
  buf[0] &= 0x7f;
  assert( n<=9 );
  for(i=0, j=n-1; j>=0; j--, i++){
    p[i] = buf[j];
  }
  return n;
}

/*
** This routine is a faster version of sqlite4PutVarint() that only
** works for 32-bit positive integers and which is optimized for
** the common case of small integers.  A MACRO version, putVarint32,
** is provided which inlines the single-byte case.  All code should use
** the MACRO version as this function assumes the single-byte case has
** already been handled.
*/
int sqlite4PutVarint32(unsigned char *p, u32 v){
#ifndef putVarint32
  if( (v & ~0x7f)==0 ){
    p[0] = v;
    return 1;
  }
#endif
  if( (v & ~0x3fff)==0 ){
    p[0] = (u8)((v>>7) | 0x80);
    p[1] = (u8)(v & 0x7f);
    return 2;
  }
  return sqlite4PutVarint(p, v);
}

/*
** Bitmasks used by sqlite4GetVarint().  These precomputed constants
** are defined here rather than simply putting the constant expressions
** inline in order to work around bugs in the RVT compiler.
**
** SLOT_2_0     A mask for  (0x7f<<14) | 0x7f
**
** SLOT_4_2_0   A mask for  (0x7f<<28) | SLOT_2_0
*/
#define SLOT_2_0     0x001fc07f
#define SLOT_4_2_0   0xf01fc07f


/*
** Read a 64-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
*/
u8 sqlite4GetVarint(const unsigned char *p, u64 *v){
  u32 a,b,s;

  a = *p;
  /* a: p0 (unmasked) */
  if (!(a&0x80))
  {
    *v = a;
    return 1;
  }

  p++;
  b = *p;
  /* b: p1 (unmasked) */
  if (!(b&0x80))
  {
    a &= 0x7f;
    a = a<<7;
    a |= b;
    *v = a;
    return 2;
  }

  /* Verify that constants are precomputed correctly */
  assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
  assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );

  p++;
  a = a<<14;
  a |= *p;
  /* a: p0<<14 | p2 (unmasked) */
  if (!(a&0x80))
  {
    a &= SLOT_2_0;
    b &= 0x7f;
    b = b<<7;
    a |= b;
    *v = a;
    return 3;
  }

  /* CSE1 from below */
  a &= SLOT_2_0;
  p++;
  b = b<<14;
  b |= *p;
  /* b: p1<<14 | p3 (unmasked) */
  if (!(b&0x80))
  {
    b &= SLOT_2_0;
    /* moved CSE1 up */
    /* a &= (0x7f<<14)|(0x7f); */
    a = a<<7;
    a |= b;
    *v = a;
    return 4;
  }

  /* a: p0<<14 | p2 (masked) */
  /* b: p1<<14 | p3 (unmasked) */
  /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
  /* moved CSE1 up */
  /* a &= (0x7f<<14)|(0x7f); */
  b &= SLOT_2_0;
  s = a;
  /* s: p0<<14 | p2 (masked) */

  p++;
  a = a<<14;
  a |= *p;
  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
  if (!(a&0x80))
  {
    /* we can skip these cause they were (effectively) done above in calc'ing s */
    /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
    /* b &= (0x7f<<14)|(0x7f); */
    b = b<<7;
    a |= b;
    s = s>>18;
    *v = ((u64)s)<<32 | a;
    return 5;
  }

  /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
  s = s<<7;
  s |= b;
  /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */

  p++;
  b = b<<14;
  b |= *p;
  /* b: p1<<28 | p3<<14 | p5 (unmasked) */
  if (!(b&0x80))
  {
    /* we can skip this cause it was (effectively) done above in calc'ing s */
    /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
    a &= SLOT_2_0;
    a = a<<7;
    a |= b;
    s = s>>18;
    *v = ((u64)s)<<32 | a;
    return 6;
  }

  p++;
  a = a<<14;
  a |= *p;
  /* a: p2<<28 | p4<<14 | p6 (unmasked) */
  if (!(a&0x80))
  {
    a &= SLOT_4_2_0;
    b &= SLOT_2_0;
    b = b<<7;
    a |= b;
    s = s>>11;
    *v = ((u64)s)<<32 | a;
    return 7;
  }

  /* CSE2 from below */
  a &= SLOT_2_0;
  p++;
  b = b<<14;
  b |= *p;
  /* b: p3<<28 | p5<<14 | p7 (unmasked) */
  if (!(b&0x80))
  {
    b &= SLOT_4_2_0;
    /* moved CSE2 up */
    /* a &= (0x7f<<14)|(0x7f); */
    a = a<<7;
    a |= b;
    s = s>>4;
    *v = ((u64)s)<<32 | a;
    return 8;
  }

  p++;
  a = a<<15;
  a |= *p;
  /* a: p4<<29 | p6<<15 | p8 (unmasked) */

  /* moved CSE2 up */
  /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
  b &= SLOT_2_0;
  b = b<<8;
  a |= b;

  s = s<<4;
  b = p[-4];
  b &= 0x7f;
  b = b>>3;
  s |= b;

  *v = ((u64)s)<<32 | a;

  return 9;
}

/*
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
**
** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
** integer, then set *v to 0xffffffff.
**
** A MACRO version, getVarint32, is provided which inlines the 
** single-byte case.  All code should use the MACRO version as 
** this function assumes the single-byte case has already been handled.
*/
u8 sqlite4GetVarint32(const unsigned char *p, u32 *v){
  u32 a,b;

  /* The 1-byte case.  Overwhelmingly the most common.  Handled inline
  ** by the getVarin32() macro */
  a = *p;
  /* a: p0 (unmasked) */
#ifndef getVarint32
  if (!(a&0x80))
  {
    /* Values between 0 and 127 */
    *v = a;
    return 1;
  }
#endif

  /* The 2-byte case */
  p++;
  b = *p;
  /* b: p1 (unmasked) */
  if (!(b&0x80))
  {
    /* Values between 128 and 16383 */
    a &= 0x7f;
    a = a<<7;
    *v = a | b;
    return 2;
  }

  /* The 3-byte case */
  p++;
  a = a<<14;
  a |= *p;
  /* a: p0<<14 | p2 (unmasked) */
  if (!(a&0x80))
  {
    /* Values between 16384 and 2097151 */
    a &= (0x7f<<14)|(0x7f);
    b &= 0x7f;
    b = b<<7;
    *v = a | b;
    return 3;
  }

  /* A 32-bit varint is used to store size information in btrees.
  ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
  ** A 3-byte varint is sufficient, for example, to record the size
  ** of a 1048569-byte BLOB or string.
  **
  ** We only unroll the first 1-, 2-, and 3- byte cases.  The very
  ** rare larger cases can be handled by the slower 64-bit varint
  ** routine.
  */
#if 1
  {
    u64 v64;
    u8 n;

    p -= 2;
    n = sqlite4GetVarint(p, &v64);
    assert( n>3 && n<=9 );
    if( (v64 & SQLITE4_MAX_U32)!=v64 ){
      *v = 0xffffffff;
    }else{
      *v = (u32)v64;
    }
    return n;
  }

#else
  /* For following code (kept for historical record only) shows an
  ** unrolling for the 3- and 4-byte varint cases.  This code is
  ** slightly faster, but it is also larger and much harder to test.
  */
  p++;
  b = b<<14;
  b |= *p;
  /* b: p1<<14 | p3 (unmasked) */
  if (!(b&0x80))
  {
    /* Values between 2097152 and 268435455 */
    b &= (0x7f<<14)|(0x7f);
    a &= (0x7f<<14)|(0x7f);
    a = a<<7;
    *v = a | b;
    return 4;
  }

  p++;
  a = a<<14;
  a |= *p;
  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
  if (!(a&0x80))
  {
    /* Values  between 268435456 and 34359738367 */
    a &= SLOT_4_2_0;
    b &= SLOT_4_2_0;
    b = b<<7;
    *v = a | b;
    return 5;
  }

  /* We can only reach this point when reading a corrupt database
  ** file.  In that case we are not in any hurry.  Use the (relatively
  ** slow) general-purpose sqlite4GetVarint() routine to extract the
  ** value. */
  {
    u64 v64;
    u8 n;

    p -= 4;
    n = sqlite4GetVarint(p, &v64);
    assert( n>5 && n<=9 );
    *v = (u32)v64;
    return n;
  }
#endif
}

/*
** Return the number of bytes that will be needed to store the given
** 64-bit integer.
*/
int sqlite4VarintLen(u64 v){
  int i = 0;
  do{
    i++;
    v >>= 7;
  }while( v!=0 && ALWAYS(i<9) );
  return i;
}


/*
** Read or write a four-byte big-endian integer value.
*/
u32 sqlite4Get4byte(const u8 *p){
  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
Changes to src/varint.c.
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
  }
  z[0] = 255;
  varintWrite32(z+1, w);
  varintWrite32(z+5, y);
  return 9;
}

/*
** Return the number of bytes required to encode value v as a varint.
*/
int sqlite4VarintLen(sqlite4_uint64 v){
  unsigned char aDummy[9];
  return sqlite4PutVarint64(aDummy, v);
}

/*
** Read a varint from buffer z and set *pResult to the value read.
** Return the number of bytes read from the buffer.
*/
int sqlite4GetVarint32(const unsigned char *z, u32 *pResult){
  sqlite4_uint64 iRes;
  int ret;
  ret = sqlite4GetVarint64(z, 9, &iRes);
  *pResult = (u32)iRes;
  return ret;
}

/*
** Encode v as a varint and write the result to buffer p. Return the
** number of bytes written.
*/
int sqlite4PutVarint32(unsigned char *p, u32 v){
  return sqlite4PutVarint64(p, v);
}

/*
** Compile this one file with the -DTEST_VARINT option to run the simple
** test case below.  The test program generates 10 million random 64-bit
** values, weighted toward smaller numbers, and for each value it encodes
** and then decodes the varint to verify that the same number comes back.
** It also checks to make sure the if x<y then memcmp(varint(x),varint(y))<0.
*/







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







220
221
222
223
224
225
226




























227
228
229
230
231
232
233
  }
  z[0] = 255;
  varintWrite32(z+1, w);
  varintWrite32(z+5, y);
  return 9;
}





























/*
** Compile this one file with the -DTEST_VARINT option to run the simple
** test case below.  The test program generates 10 million random 64-bit
** values, weighted toward smaller numbers, and for each value it encodes
** and then decodes the varint to verify that the same number comes back.
** It also checks to make sure the if x<y then memcmp(varint(x),varint(y))<0.
*/
Changes to src/vdbe.c.
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
  VdbeCursor *pCx = 0;
  nByte = 
      ROUND8(sizeof(VdbeCursor)) + 
      2*nField*sizeof(u32);

  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite4VdbeFreeCursor(p->apCsr[iCur]);
    p->apCsr[iCur] = 0;
  }
  if( SQLITE4_OK==sqlite4VdbeMemGrow(pMem, nByte, 0) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, sizeof(VdbeCursor));
    pCx->db = p->db;
    pCx->iDb = iDb;
    pCx->nField = nField;
    pCx->rowChnged = 1;
    sqlite4_buffer_init(&pCx->sSeekKey, p->db->pEnv->pMM);
  }
  return pCx;
}

/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information.  In other words, if the string







|





<


<
<







206
207
208
209
210
211
212
213
214
215
216
217
218

219
220


221
222
223
224
225
226
227
  VdbeCursor *pCx = 0;
  nByte = 
      ROUND8(sizeof(VdbeCursor)) + 
      2*nField*sizeof(u32);

  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite4VdbeFreeCursor(p, p->apCsr[iCur]);
    p->apCsr[iCur] = 0;
  }
  if( SQLITE4_OK==sqlite4VdbeMemGrow(pMem, nByte, 0) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, sizeof(VdbeCursor));

    pCx->iDb = iDb;
    pCx->nField = nField;


  }
  return pCx;
}

/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information.  In other words, if the string
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864

/* Opcode: Integer P1 P2 * * *
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_Integer: {         /* out2-prerelease */
  pOut->u.num = sqlite4_num_from_int64((i64)pOp->p1);
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}

/* Opcode: Num P1 P2 * P4 *
**
** P4 is a pointer to an sqlite4_num value. Write that value into 
** register P2. Set the register flags to MEM_Int if P1 is non-zero,







<







847
848
849
850
851
852
853

854
855
856
857
858
859
860

/* Opcode: Integer P1 P2 * * *
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_Integer: {         /* out2-prerelease */
  pOut->u.num = sqlite4_num_from_int64((i64)pOp->p1);

  break;
}

/* Opcode: Num P1 P2 * P4 *
**
** P4 is a pointer to an sqlite4_num value. Write that value into 
** register P2. Set the register flags to MEM_Int if P1 is non-zero,
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
        pOut->u.num = sqlite4_num_mul(num1, num2); break;
      case OP_Divide: 
        pOut->u.num = sqlite4_num_div(num2, num1); break;
      default: {
        iA = sqlite4_num_to_int64(num1, 0);
        iB = sqlite4_num_to_int64(num2, 0);
        if( iA==0 ) goto arithmetic_result_is_null;
        if( iA==-1 ) iA = 1;
        pOut->u.num = sqlite4_num_from_int64(iB % iA);
        break;
      }
    }

    if( sqlite4_num_isnan(pOut->u.num) ){
      goto arithmetic_result_is_null;







<







1254
1255
1256
1257
1258
1259
1260

1261
1262
1263
1264
1265
1266
1267
        pOut->u.num = sqlite4_num_mul(num1, num2); break;
      case OP_Divide: 
        pOut->u.num = sqlite4_num_div(num2, num1); break;
      default: {
        iA = sqlite4_num_to_int64(num1, 0);
        iB = sqlite4_num_to_int64(num2, 0);
        if( iA==0 ) goto arithmetic_result_is_null;

        pOut->u.num = sqlite4_num_from_int64(iB % iA);
        break;
      }
    }

    if( sqlite4_num_isnan(pOut->u.num) ){
      goto arithmetic_result_is_null;
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837

  /* Undo any changes made by applyAffinity() to the input registers. */
  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
  break;
}

/* Opcode: Permutation P1 * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.  P4 will contain exactly P1 elements.  The P1
** parameter is used only for printing the P4 array when debugging.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
*/
case OP_Permutation: {
  assert( pOp->p4type==P4_INTARRAY );







|


|
<







1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824

1825
1826
1827
1828
1829
1830
1831

  /* Undo any changes made by applyAffinity() to the input registers. */
  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
  break;
}

/* Opcode: Permutation * * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.

**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
*/
case OP_Permutation: {
  assert( pOp->p4type==P4_INTARRAY );
2097
2098
2099
2100
2101
2102
2103


2104
2105
2106
2107


2108

2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120


2121
















2122
2123
2124
2125
2126

2127
2128
2129


2130
2131
2132
2133
2134

2135
2136
2137
2138
2139
2140
2141
**
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
*/
case OP_Column: {


  int p1;                   /* Index of VdbeCursor to decode */
  int mxField;              /* Maximum column number */
  VdbeCursor *pC;           /* The VDBE cursor */
  Mem *pDest;               /* Where to write the results */


  Mem *pDefault;            /* Default value from P4 */


  p1 = pOp->p1;
  assert( p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pDest = &aMem[pOp->p3];
  memAboutToChange(p, pDest);
  pC = p->apCsr[p1];
  assert( pC!=0 );
  assert( pC->iRoot!=KVSTORE_ROOT );
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  assert( pC->pVtabCursor==0 );
#endif


  if( pC->pDecoder==0 ){
















    mxField = pC->nField;
    if( pC->pKeyInfo && pC->pKeyInfo->nData ) mxField = pC->pKeyInfo->nData;
    rc = sqlite4VdbeDecoderCreate(db, pC, 0, mxField, &pC->pDecoder);
    pC->rowChnged = 1;
  }

  if( rc==SQLITE4_OK ){
    pDefault = (pOp->p4type==P4_MEM) ? pOp->p4.pMem : 0;
    rc = sqlite4VdbeDecoderGetColumn(pC->pDecoder, pOp->p2, pDefault, pDest);


  }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.
**







>
>

<


>
>

>








<



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





>







2091
2092
2093
2094
2095
2096
2097
2098
2099
2100

2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119
2120
2121
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
**
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
*/
case OP_Column: {
  KVCursor *pKVCur;         /* Cursor for current entry in the KV storage */
  ValueDecoder *pCodec;     /* The decoder object */
  int p1;                   /* Index of VdbeCursor to decode */

  VdbeCursor *pC;           /* The VDBE cursor */
  Mem *pDest;               /* Where to write the results */
  const KVByteArray *aData; /* The content to be decoded */
  KVSize nData;             /* Size of aData[] in bytes */
  Mem *pDefault;            /* Default value from P4 */
  Mem *pReg;                /* */

  p1 = pOp->p1;
  assert( p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pDest = &aMem[pOp->p3];
  memAboutToChange(p, pDest);
  pC = p->apCsr[p1];
  assert( pC!=0 );

#ifndef SQLITE4_OMIT_VIRTUALTABLE
  assert( pC->pVtabCursor==0 );
#endif
  pKVCur = pC->pKVCur;
  if( pKVCur!=0 ){
    if( pC->nullRow ){
      aData = 0;
    }else{
      rc = sqlite4KVCursorData(pKVCur, 0, -1, &aData, &nData);
    }
  }else if( ALWAYS(pC->pseudoTableReg>0) ){
    pReg = &aMem[pC->pseudoTableReg];
    assert( pReg->flags & MEM_Blob );
    assert( memIsValid(pReg) );
    aData = (const KVByteArray*)pReg->z;
    nData = pReg->n;
  }else{
    aData = 0;
    MemSetTypeFlag(pDest, MEM_Null);
  }
  if( rc==SQLITE4_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);
      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.
**
2162
2163
2164
2165
2166
2167
2168
2169


2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
  break;
}

/* Opcode: MakeIdxKey P1 P2 P3 P4 P5
**
** 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 taken from the KeyInfo object of P1.  However, of P4 is a positive


** integer, P4 is used for N instead.
**
** 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. 
**
** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
** (unique within the cursor) is appended to the record. The sole purpose
** of this is to ensure that the key blob is unique within the cursor table.
**
** If the OPFLAG_PARTIALKEY bit of P5 is set, that means the value supplied
** for N is not the true number of values in the key, only the number that
** need to be encoded for this operation.  This effects the encoding of
** final BLOBs.
*/
case OP_MakeIdxKey: {







|
>
>
|







|







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
  break;
}

/* Opcode: MakeIdxKey P1 P2 P3 P4 P5
**
** 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. 
**
** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
** (unique within the cursor) is appended to the record. The sole purpose
** of this is to ensure that the key blob is unique within the cursors table.
**
** If the OPFLAG_PARTIALKEY bit of P5 is set, that means the value supplied
** for N is not the true number of values in the key, only the number that
** need to be encoded for this operation.  This effects the encoding of
** final BLOBs.
*/
case OP_MakeIdxKey: {
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
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  /* If P4 contains OPFLAG_SEQCOUNT, encode the sequence number blob to be
  ** appended to the end of the key.  Variable nSeq is set to the number
  ** of bytes in the encoded key.  A non-standard encoding is used (not
  ** the usual varint encoding) so that the OP_GrpCompare opcode can easily
  ** back up over the sequence count to find the true end of the key.
  */
  nSeq = 0;
  if( pOp->p5 & OPFLAG_SEQCOUNT ){
    iSeq = pC->seqCount++;
    do {
      nSeq++;
      aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
      iSeq = iSeq >> 7;
    }while( iSeq );
    aSeq[sizeof(aSeq)-nSeq] |= 0x80;
  }

  memAboutToChange(p, pOut);


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

  if( rc ){
    sqlite4DbFree(db, aRec);
  }else{
    if( nSeq ){







|
|
|
<
<














>
|


<
<


|







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
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  /* If pOp->p5 is non-zero, encode the sequence number blob to append to
  ** the end of the key. Variable nSeq is set to the number of bytes in
  ** the encoded key.


  */
  nSeq = 0;
  if( pOp->p5 & OPFLAG_SEQCOUNT ){
    iSeq = pC->seqCount++;
    do {
      nSeq++;
      aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
      iSeq = iSeq >> 7;
    }while( iSeq );
    aSeq[sizeof(aSeq)-nSeq] |= 0x80;
  }

  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, nField+(pOp->p5 & OPFLAG_PARTIALKEY),
    pC->iRoot, pKeyInfo, &aRec, &nRec, nSeq
  );

  if( rc ){
    sqlite4DbFree(db, aRec);
  }else{
    if( nSeq ){
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
**
** 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 SQLITE4_AFF_ macros defined in sqliteInt.h. If P4 is NULL
** then all index fields have the affinity NONE.
**
** If this instruction is immediately preceded by OP_Permutation, then the
** specified permutation is used to determine the order that registers are
** used to build the record.  The i-th column of the record is taken from
** register P1+aPermute[i].  If OP_Permutation has not been run, then the i-th
** column comes from register P1+i.
**
** This opcode applies the affinities that it specifies to the input
** array elements. Then, 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 */
  char *zAffinity;       /* The affinity string for the record */
  VdbeCursor *pC;        /* Cursor to generate key for */
  Mem *pKeyOut;          /* Where to store the generated key */
  int keyReg;            /* Register into which to write the key */
  u8 *aRec;              /* The constructed key or value */
  int nRec;              /* Size of aRec[] in bytes */

  assert( aPermute==0 || pOp->opcode!=OP_MakeKey );
  assert( aPermute==0 || pOp->p4type==P4_NOTUSED );
  assert( aPermute==0 || pOp->p3 );

  if( pOp->opcode==OP_MakeKey ){
    pC = p->apCsr[pOp->p1];
    keyReg = pOp->p2;
    pKeyOut = &aMem[keyReg];
    memAboutToChange(p, pKeyOut);
    assert( pC!=0 );
    assert( pC->pKeyInfo!=0 );
    pc++;
    pOp++;
    assert( pOp->opcode==OP_MakeRecord );
#ifdef SQLITE4_DEBUG
    if( p->trace ) sqlite4VdbePrintOp(p->trace, pc, pOp);
#endif
  }else{
    pC = 0;
  }

  zAffinity = pOp->p4.z;
  assert( pOp->p1>0 && pOp->p2>0 && pOp->p2+pOp->p1<=p->nMem+1 );
  pData0 = &aMem[pOp->p1];
  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++){







|
<
<
<
<
<
|
|


















<
<
<
<
















>

|
|







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
2321
2322
2323
2324
2325
2326
**
** 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 SQLITE4_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 */
  char *zAffinity;       /* The affinity string for the record */
  VdbeCursor *pC;        /* Cursor to generate key for */
  Mem *pKeyOut;          /* Where to store the generated key */
  int keyReg;            /* Register into which to write the key */
  u8 *aRec;              /* The constructed key or value */
  int nRec;              /* Size of aRec[] in bytes */





  if( pOp->opcode==OP_MakeKey ){
    pC = p->apCsr[pOp->p1];
    keyReg = pOp->p2;
    pKeyOut = &aMem[keyReg];
    memAboutToChange(p, pKeyOut);
    assert( pC!=0 );
    assert( pC->pKeyInfo!=0 );
    pc++;
    pOp++;
    assert( pOp->opcode==OP_MakeRecord );
#ifdef SQLITE4_DEBUG
    if( p->trace ) sqlite4VdbePrintOp(p->trace, pc, pOp);
#endif
  }else{
    pC = 0;
  }
  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++){
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
      rc = sqlite4VdbeMemSetStr(pKeyOut, (char *)aRec, nRec, 0,
                                SQLITE4_DYNAMIC, 0);
      REGISTER_TRACE(keyReg, pKeyOut);
      UPDATE_MAX_BLOBSIZE(pKeyOut);
    }
  }

  /* If P3 is not 0, compute the data record */
  if( rc==SQLITE4_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, aPermute, nField, &aRec, &nRec);
    if( rc ){
      sqlite4DbFree(db, aRec);
    }else{
      rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec, 0, SQLITE4_DYNAMIC,0);
      REGISTER_TRACE(pOp->p3, pOut);
      UPDATE_MAX_BLOBSIZE(pOut);
    }
  }
  aPermute = 0;
  break;
}

/* Opcode: Count P1 P2 * * *
**
** Store the number of entries (an integer value) in the table or index 
** opened by cursor P1 in register P2







|





|








<







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
      rc = sqlite4VdbeMemSetStr(pKeyOut, (char *)aRec, nRec, 0,
                                SQLITE4_DYNAMIC, 0);
      REGISTER_TRACE(keyReg, pKeyOut);
      UPDATE_MAX_BLOBSIZE(pKeyOut);
    }
  }

  /* If P3 is not 0, compute the data rescord */
  if( rc==SQLITE4_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, (char *)aRec, nRec, 0, SQLITE4_DYNAMIC,0);
      REGISTER_TRACE(pOp->p3, pOut);
      UPDATE_MAX_BLOBSIZE(pOut);
    }
  }

  break;
}

/* Opcode: Count P1 P2 * * *
**
** Store the number of entries (an integer value) in the table or index 
** opened by cursor P1 in register P2
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
        p->nStmtDefCons = db->nDeferredCons;
      }
    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 * * *
**
** Read the schema cookie from database P1 and write it into register P2.
**
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: {               /* out2-prerelease */
  unsigned int iMeta;
  KVStore *pKV;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pKV = db->aDb[pOp->p1].pKV;
  rc = sqlite4KVStoreGetSchema(pKV, &iMeta);
  pOut->u.num = sqlite4_num_from_int64(iMeta);
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}

/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
** into cookie number P2 of database P1.  P2==1 is the schema version.  
** P2==2 is the database format. P2==3 is the recommended pager cache 
** size, and so forth.  P1==0 is the main database file and P1==1 is the 
** database file used to store temporary tables.







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







2540
2541
2542
2543
2544
2545
2546




















2547
2548
2549
2550
2551
2552
2553
        p->nStmtDefCons = db->nDeferredCons;
      }
    }
  }
  break;
}





















/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
** into cookie number P2 of database P1.  P2==1 is the schema version.  
** P2==2 is the database format. P2==3 is the recommended pager cache 
** size, and so forth.  P1==0 is the main database file and P1==1 is the 
** database file used to store temporary tables.
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
    if( NEVER(p2<2) ) {
      rc = SQLITE4_CORRUPT_BKPT;
      goto abort_due_to_error;
    }
  }
  if( pOp->p4type==P4_KEYINFO ){
    pKeyInfo = pOp->p4.pKeyInfo;

    nField = pKeyInfo->nField+1;
  }else if( pOp->p4type==P4_INT32 ){
    nField = pOp->p4.i;
  }
  assert( pOp->p1>=0 );
  pCur = allocateCursor(p, pOp->p1, nField, iDb, 1);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;

  pCur->iRoot = p2;
  rc = sqlite4KVStoreOpenCursor(pX, &pCur->pKVCur);
  pCur->pKeyInfo = pKeyInfo;







  break;
}

/* Opcode: OpenEphemeral P1 P2 * P4 P5
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 







>








>



>
>
>
>
>
>
>







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
    if( NEVER(p2<2) ) {
      rc = SQLITE4_CORRUPT_BKPT;
      goto abort_due_to_error;
    }
  }
  if( pOp->p4type==P4_KEYINFO ){
    pKeyInfo = pOp->p4.pKeyInfo;
    pKeyInfo->enc = ENC(p->db);
    nField = pKeyInfo->nField+1;
  }else if( pOp->p4type==P4_INT32 ){
    nField = pOp->p4.i;
  }
  assert( pOp->p1>=0 );
  pCur = allocateCursor(p, pOp->p1, nField, iDb, 1);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;
  pCur->isOrdered = 1;
  pCur->iRoot = p2;
  rc = sqlite4KVStoreOpenCursor(pX, &pCur->pKVCur);
  pCur->pKeyInfo = pKeyInfo;

  /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
  ** SQLite used to check if the root-page flags were sane at this point
  ** and report database corruption if they were not, but this check has
  ** since moved into the btree layer.  */  
  pCur->isTable = pOp->p4type!=P4_KEYINFO;
  pCur->isIndex = !pCur->isTable;
  break;
}

/* Opcode: OpenEphemeral P1 P2 * P4 P5
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
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

2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863


2864
2865
2866
2867
2868

2869

2870
2871
2872
2873
2874


2875
2876




2877
2878
2879
2880
2881
2882
2883
2884
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
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
3027
3028
3029
3030
3031
3032
3033
3034

3035
3036
3037
3038
3039
3040
3041
  rc = sqlite4KVStoreOpen(db, "ephm", 0, &pCx->pTmpKV,
          SQLITE4_KVOPEN_TEMPORARY | SQLITE4_KVOPEN_NO_TRANSACTIONS
  );
  if( rc==SQLITE4_OK ) rc = sqlite4KVStoreOpenCursor(pCx->pTmpKV, &pCx->pKVCur);
  if( rc==SQLITE4_OK ) rc = sqlite4KVStoreBegin(pCx->pTmpKV, 2);

  pCx->pKeyInfo = pOp->p4.pKeyInfo;




  break;
}

/* Opcode: OpenSorter P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
  /* VdbeCursor *pCx; */
  pOp->opcode = OP_OpenEphemeral;
  pc--;
  break;
}





























/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  sqlite4VdbeFreeCursor(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.
**
** Actually, the seek is deferred until it is actually needed and if the
** PRIMARY KEY index is never referenced, the seek never takes place.  The
** sqlite3VdbeCursorMoveto() does the seek, if necessary.  If the target
** row does not exist in the PRIMARY KEY table, then the
** sqlite3VdbeCursorMoveto() routine will throw an SQLITE4_CORRUPT error.
*/
case OP_SeekPk: {
  KVByteArray *aKey;              /* Key data from cursor pIdx */
  KVSize nKey;                    /* Size of aKey[] in bytes */
  VdbeCursor *pPk;                /* Cursor P1 */
  VdbeCursor *pIdx;               /* Cursor P3 */


  int nShort;                     /* Size of aKey[] without PK fields */

  int nVarint;                    /* Size of varint pPk->iRoot */

  pPk = p->apCsr[pOp->p1];
  pIdx = p->apCsr[pOp->p3];

  if( pIdx->pFts ){
    rc = sqlite4Fts5Pk(pIdx->pFts, pPk->iRoot, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      rc = sqlite4KVCursorSeek(pPk->pKVCur, aKey, nKey, 0);
      if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT;
      pPk->nullRow = 0;
    }
  }else{


    rc = sqlite4KVCursorKey(pIdx->pKVCur, (const KVByteArray **)&aKey, &nKey);
    if( rc!=SQLITE4_OK ) break;
    nShort = sqlite4VdbeShortKey(aKey, nKey, 
        pIdx->pKeyInfo->nField - pIdx->pKeyInfo->nPK, 0
    );

    nVarint = sqlite4VarintLen(pPk->iRoot);

    rc = sqlite4_buffer_resize(&pPk->sSeekKey, nVarint + nKey - nShort);
    if( rc!=SQLITE4_OK ) break;
    putVarint32((u8 *)(pPk->sSeekKey.p), pPk->iRoot);
    memcpy(((u8*)pPk->sSeekKey.p) + nVarint, &aKey[nShort], nKey-nShort);
    assert( pPk->sSeekKey.n>0 );


  }
  pPk->rowChnged = 1;





  break;
}

/* Opcode: SeekGe P1 P2 P3 P4 *
**
** P1 identifies an open database cursor. The cursor is repositioned so
** that it points to the smallest entry in its index that is greater than
** or equal to the key formed by the array of P4 registers starting at
** register P3.
**

** 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 *
**
** P1 identifies an open database cursor. The cursor is repositioned so
** that it points to the smallest entry in its index that is greater than
** the key formed by the array of P4 registers starting at
** register P3.
**

** If there are no records greater than the key and P2 is 
** not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
*/
/* Opcode: SeekLt P1 P2 P3 P4 * 
**
** P1 identifies an open database cursor. The cursor is repositioned so
** that it points to the largest entry in its index that is less than
** the key formed by the array of P4 registers starting at
** register P3.
**

** If there are no records less than the key and P2 is 
** not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
*/
/* Opcode: SeekLe P1 P2 P3 P4 *
**
** P1 identifies an open database cursor. The cursor is repositioned so
** that it points to the largest entry in its index that is less than or
** equal to the key formed by the array of P4 registers starting at
** register P3.
**

** If there are no records less than or equal to the key and P2 is 
** not zero, then jump to P2.
**
** 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;
  pC->sSeekKey.n = 0;
  pC->rowChnged = 1;

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

  assert( OP_SeekLe == OP_SeekLt+1 );
  assert( OP_SeekGe == OP_SeekLt+2 );
  assert( OP_SeekGt == OP_SeekLt+3 );

  dir = +1;
  op = pOp->opcode;
  if( op==OP_SeekLe || op==OP_SeekLt ) dir = -1;

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

  nField = pOp->p4.i;
  pIn3 = &aMem[pOp->p3];
  if( pC->iRoot!=KVSTORE_ROOT ){
    rc = sqlite4VdbeEncodeKey(
        db, pIn3, nField, nField+(pOp->p5 & OPFLAG_PARTIALKEY),
        pC->iRoot, pC->pKeyInfo, &aProbe, &nProbe, 1
    );

    /*   Opcode    search-dir    increment-key
    **  --------------------------------------
    **   SeekLt    -1            no
    **   SeekLe    -1            yes
    **   SeekGe    +1            no
    **   SeekGt    +1            yes
    */


    if( op==OP_SeekLe || op==OP_SeekGt ) aProbe[nProbe++] = 0xFF;
    if( rc==SQLITE4_OK ){
      rc = sqlite4KVCursorSeek(pC->pKVCur, aProbe, nProbe, dir);
    }
  }else{
    Stringify(pIn3, encoding);
    rc = sqlite4KVCursorSeek(
        pC->pKVCur, (const KVByteArray *)pIn3->z, pIn3->n, dir
    );
  }

  if( rc==SQLITE4_OK ){
    if( op==OP_SeekLt ){
      rc = sqlite4KVCursorPrev(pC->pKVCur);
    }else if( op==OP_SeekGt ){
      rc = sqlite4KVCursorNext(pC->pKVCur);
    }
  }

  if( pC->iRoot!=KVSTORE_ROOT ){
    /* Check that the KV cursor currently points to an entry belonging
    ** to index pC->iRoot (and not an entry that is part of some other 
    ** index).  */
    if( rc==SQLITE4_OK || rc==SQLITE4_INEXACT ){
      rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
      if( rc==SQLITE4_OK && memcmp(aKey, aProbe, sqlite4VarintLen(pC->iRoot)) ){
        rc = SQLITE4_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);
  }else if( rc==SQLITE4_INEXACT ){
    rc = SQLITE4_OK;
  }

  if( rc==SQLITE4_NOTFOUND ){
    rc = SQLITE4_OK;
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
**
** P1 is an open table cursor and P2 is a rowid integer.  Arrange
** for P1 to move so that it points to the rowid given by P2.
*/
case OP_Seek: {    /* in2 */
  VdbeCursor *pC;
  KVCursor *pKVCur;
  KVByteArray *aKey;
  KVSize nKey;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  pC->rowChnged = 1;
  assert( pC!=0 );

  pKVCur = pC->pKVCur;
  rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, 1, pC->iRoot, 0,
                            &aKey, &nKey, 0);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorSeek(pKVCur, aKey, nKey, 0);
    if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT;
  }







>
>

>















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








|












|
<
<
<
<
<
|


<
<


>
>

>
|





|

|




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






|
|
|
|

>
|
|





|
|
|
|

>
|
|





|
|
|
|

>
|
|





|
|
|
|

>
|
|


















<
<




>



|
<
<
<




>


<
|
|
|
|

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










<
|
|
|
|
|
|
|
|
|

|
|
|
<
<
<
<




















<

>







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
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864





2865
2866
2867


2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
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
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
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036




3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056

3057
3058
3059
3060
3061
3062
3063
3064
3065
  rc = sqlite4KVStoreOpen(db, "ephm", 0, &pCx->pTmpKV,
          SQLITE4_KVOPEN_TEMPORARY | SQLITE4_KVOPEN_NO_TRANSACTIONS
  );
  if( rc==SQLITE4_OK ) rc = sqlite4KVStoreOpenCursor(pCx->pTmpKV, &pCx->pKVCur);
  if( rc==SQLITE4_OK ) rc = sqlite4KVStoreBegin(pCx->pTmpKV, 2);

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

  pCx->isOrdered = 1;
  break;
}

/* Opcode: OpenSorter P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
  /* VdbeCursor *pCx; */
  pOp->opcode = OP_OpenEphemeral;
  pc--;
  break;
}

/* Opcode: OpenPseudo P1 P2 P3 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data.  The content of that one row is the content of memory
** register P2.  In other words, cursor P1 becomes an alias for the 
** MEM_Blob content contained in register P2.
**
** A pseudo-table created by this opcode is used to hold a single
** row output from the sorter so that the row can be decomposed into
** individual columns using the OP_Column opcode.  The OP_Column opcode
** is the only cursor opcode that works with a pseudo-table.
**
** P3 is the number of fields in the records that will be stored by
** the pseudo-table.
*/
case OP_OpenPseudo: {
  VdbeCursor *pCx;

  assert( pOp->p1>=0 );
  pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->pseudoTableReg = pOp->p2;
  pCx->isTable = 1;
  pCx->isIndex = 0;
  break;
}

/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
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 SQLITE4_CORRUPT exception.
*/
case OP_SeekPk: {


  VdbeCursor *pPk;                /* Cursor P1 */
  VdbeCursor *pIdx;               /* Cursor P3 */
  KVByteArray const *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;

  pPk = p->apCsr[pOp->p1];
  pIdx = p->apCsr[pOp->p3];

  if( pIdx->pFts ){
    rc = sqlite4Fts5Pk(pIdx->pFts, pPk->iRoot, &aPkKey, &nPkKey);
    if( rc==SQLITE4_OK ){
      rc = sqlite4KVCursorSeek(pPk->pKVCur, aPkKey, nPkKey, 0);
      if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT;
      pPk->nullRow = 0;
    }
  }else{
    assert( pIdx->pKeyInfo->nPK>0 );
    assert( pPk->pKeyInfo->nPK==0 );
    rc = sqlite4KVCursorKey(pIdx->pKVCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      nShort = sqlite4VdbeShortKey(aKey, nKey, 
          pIdx->pKeyInfo->nField - pIdx->pKeyInfo->nPK, 0
      );

      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==SQLITE4_NOTFOUND ){
          rc = SQLITE4_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 *
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), 
** use the value in register P3 as a 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 the key value. If there are no records greater than 
** the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
*/
/* Opcode: SeekLt 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 a 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 largest entry that 
** is less than the key value. If there are no records less than 
** the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
*/
/* Opcode: SeekLe 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 a 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 largest entry that 
** is less than or equal to the key value. If there are no records 
** less than or equal to the key and P2 is not zero, then jump to P2.
**
** 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, nField+(pOp->p5 & OPFLAG_PARTIALKEY),
      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==SQLITE4_OK ){
    rc = sqlite4KVCursorSeek(pC->pKVCur, aProbe, nProbe, dir);






  }

  if( rc==SQLITE4_OK ){
    if( op==OP_SeekLt ){
      rc = sqlite4KVCursorPrev(pC->pKVCur);
    }else if( op==OP_SeekGt ){
      rc = sqlite4KVCursorNext(pC->pKVCur);
    }
  }


  /* Check that the KV cursor currently points to an entry belonging
  ** to index pC->iRoot (and not an entry that is part of some other 
  ** index).  */
  if( rc==SQLITE4_OK || rc==SQLITE4_INEXACT ){
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE4_OK && memcmp(aKey, aProbe, sqlite4VarintLen(pC->iRoot)) ){
      rc = SQLITE4_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==SQLITE4_NOTFOUND ){
    rc = SQLITE4_OK;
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
**
** P1 is an open table cursor and P2 is a rowid integer.  Arrange
** for P1 to move so that it points to the rowid given by P2.
*/
case OP_Seek: {    /* in2 */
  VdbeCursor *pC;
  KVCursor *pKVCur;
  KVByteArray *aKey;
  KVSize nKey;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];

  assert( pC!=0 );
  assert( pC->isTable );
  pKVCur = pC->pKVCur;
  rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, 1, pC->iRoot, 0,
                            &aKey, &nKey, 0);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorSeek(pKVCur, aKey, nKey, 0);
    if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT;
  }
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112

3113
3114
3115
3116
3117
3118
3119
  sqlite4_found_count++;
#endif

  alreadyExists = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p4type==P4_INT32 );
  pC = p->apCsr[pOp->p1];
  pC->sSeekKey.n = 0;
  pC->rowChnged = 1;
  assert( pC!=0 );
  pIn3 = &aMem[pOp->p3];
  assert( pC->pKVCur!=0 );

  if( pOp->p4.i>0 ){
    rc = sqlite4VdbeEncodeKey(
        db, pIn3, pOp->p4.i, pOp->p4.i + (pOp->p5 & OPFLAG_PARTIALKEY),
        pC->iRoot, pC->pKeyInfo, &pProbe, &nProbe, 0
    );
    pFree = pProbe;
  }else{







<
<



>







3125
3126
3127
3128
3129
3130
3131


3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
  sqlite4_found_count++;
#endif

  alreadyExists = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p4type==P4_INT32 );
  pC = p->apCsr[pOp->p1];


  assert( pC!=0 );
  pIn3 = &aMem[pOp->p3];
  assert( pC->pKVCur!=0 );
  assert( pC->isTable==0 || pOp->opcode==OP_NotExists );
  if( pOp->p4.i>0 ){
    rc = sqlite4VdbeEncodeKey(
        db, pIn3, pOp->p4.i, pOp->p4.i + (pOp->p5 & OPFLAG_PARTIALKEY),
        pC->iRoot, pC->pKeyInfo, &pProbe, &nProbe, 0
    );
    pFree = pProbe;
  }else{
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
  KVByteArray const *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];
  pC->rowChnged = 1;
  pOut = (pOp->p4.i==0 ? 0 : &aMem[pOp->p4.i]);
  assert( pOut==0 || (pOut->flags & MEM_Blob) );

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







<







3193
3194
3195
3196
3197
3198
3199

3200
3201
3202
3203
3204
3205
3206
  KVByteArray const *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((u8 *)pProbe->z, pProbe->n, 
      pC->pKeyInfo->nField - pC->pKeyInfo->nPK, 0
  );
  assert( nShort<=pProbe->n );
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
case OP_NewRowid: {           /* out2-prerelease */
  i64 v;                   /* The new rowid */
  VdbeCursor *pC;          /* Cursor of table to get the new rowid */
  const KVByteArray *aKey; /* Key of an existing row */
  KVSize nKey;             /* Size of the existing row key */
  int n;                   /* Number of bytes decoded */
  i64 i3;                  /* Integer value from pIn3 */
  sqlite4_num vNum;        /* Intermediate result */

  v = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );

  /* Some compilers complain about constants of the form 0x7fffffffffffffff.







<







3261
3262
3263
3264
3265
3266
3267

3268
3269
3270
3271
3272
3273
3274
case OP_NewRowid: {           /* out2-prerelease */
  i64 v;                   /* The new rowid */
  VdbeCursor *pC;          /* Cursor of table to get the new rowid */
  const KVByteArray *aKey; /* Key of an existing row */
  KVSize nKey;             /* Size of the existing row key */
  int n;                   /* Number of bytes decoded */
  i64 i3;                  /* Integer value from pIn3 */


  v = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );

  /* Some compilers complain about constants of the form 0x7fffffffffffffff.
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      n = sqlite4GetVarint64((u8 *)aKey, nKey, (u64 *)&v);
      if( n==0 ) rc = SQLITE4_CORRUPT_BKPT;
      if( v!=pC->iRoot ) rc = SQLITE4_CORRUPT_BKPT;
    }
    if( rc==SQLITE4_OK ){
      n = sqlite4VdbeDecodeNumericKey(&aKey[n], nKey-n, &vNum);
      if( n==0 || (v = sqlite4_num_to_int64(vNum,0))==LARGEST_INT64 ){
        assert( 0 );
        rc = SQLITE4_FULL;
      }
    }
  }else{
    break;
  }







|
|







3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      n = sqlite4GetVarint64((u8 *)aKey, nKey, (u64 *)&v);
      if( n==0 ) rc = SQLITE4_CORRUPT_BKPT;
      if( v!=pC->iRoot ) rc = SQLITE4_CORRUPT_BKPT;
    }
    if( rc==SQLITE4_OK ){
      n = sqlite4VdbeDecodeIntKey(&aKey[n], nKey-n, &v);
      if( n==0 || v==LARGEST_INT64 ){
        assert( 0 );
        rc = SQLITE4_FULL;
      }
    }
  }else{
    break;
  }
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
3382
3383
3384
3385
3386
3387
3388
3389
3390
  }else{
    i1 = iMax+1;
  }
  pIn1->u.num = sqlite4_num_from_int64(i1);

  break;
}















































































/* Opcode: Delete P1 P2 * * *
**
** Delete the record at which the P1 cursor is currently pointing.
**
** The cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op.  Hence it is OK to delete
** a record from within an Next loop.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
**
** P1 must not be pseudo-table. It has to be a real table.
*/
case OP_Delete: {
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->sSeekKey.n==0 );
  pC->rowChnged = 1;
  rc = sqlite4KVCursorDelete(pC->pKVCur);
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}

/* Opcode: ResetCount * * * * *
**







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




















<
<







3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480


3481
3482
3483
3484
3485
3486
3487
  }else{
    i1 = iMax+1;
  }
  pIn1->u.num = sqlite4_num_from_int64(i1);

  break;
}

/* Opcode: Insert P1 P2 P3 P4 P5
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value MEM_Blob stored in register
** number P2. The key is stored in register P3. The key must
** be a MEM_Int.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P5 is set,
** then rowid is stored for subsequent return by the
** sqlite4_last_insert_rowid() function (otherwise it is unmodified).
**
** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
** UPDATE operation.  Otherwise (if the flag is clear) then this opcode
** is part of an INSERT operation.  The difference is only important to
** the update hook.
**
** Parameter P4 may point to a string containing the table-name, or 
** may be NULL. If it is not NULL, then the update-hook 
** (sqlite4.xUpdateCallback) is invoked following a successful insert.
**
** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
** allocated, then ownership of P2 is transferred to the pseudo-cursor
** and register P2 becomes ephemeral.  If the cursor is changed, the
** value of register P2 will then change.  Make sure this does not
** cause any problems.)
**
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
*/
case OP_Insert:
case OP_InsertInt: {
  Mem *pData;       /* MEM cell holding data for the record to be inserted */
  Mem *pKey;        /* MEM cell holding key  for the record */
  i64 iKey;         /* The integer ROWID or key for the record to be inserted */
  VdbeCursor *pC;   /* Cursor to table into which insert is written */
  int n;
  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);
    iKey = sqlite4_num_to_int64(pKey->u.num, 0);
  }else{
    /* assert( pOp->opcode==OP_InsertInt ); */
    iKey = pOp->p3;
  }

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pData->flags & MEM_Null ){
    pData->z = 0;
    pData->n = 0;
  }else{
    assert( pData->flags & (MEM_Blob|MEM_Str) );
  }
  n = sqlite4PutVarint64(aKey, pC->iRoot);
  n += sqlite4VdbeEncodeIntKey(&aKey[n], iKey);
  rc = sqlite4KVStoreReplace(pC->pKVCur->pStore, aKey, n,
                             (const KVByteArray*)pData->z, pData->n);

  break;
}

/* Opcode: Delete P1 P2 * * *
**
** Delete the record at which the P1 cursor is currently pointing.
**
** The cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op.  Hence it is OK to delete
** a record from within an Next loop.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
**
** P1 must not be pseudo-table. It has to be a real table.
*/
case OP_Delete: {
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );


  rc = sqlite4KVCursorDelete(pC->pKVCur);
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}

/* Opcode: ResetCount * * * * *
**
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487

3488
3489
3490
3491
3492
3493
3494

  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];
  rc = sqlite4VdbeCursorMoveto(pC);
  if( rc!=SQLITE4_OK ) break;
  assert( pC->nullRow==0 );

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

  if( pOp->opcode==OP_RowKey ){
    rc = sqlite4KVCursorKey(pCrsr, &pData, &nData);
    if( pOp->p5 ){
      nData = sqlite4VdbeShortKey(pData, nData, 1, 0);







<
|

>







3575
3576
3577
3578
3579
3580
3581

3582
3583
3584
3585
3586
3587
3588
3589
3590
3591

  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!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTableReg==0 );
  assert( pC->pKVCur!=0 );
  pCrsr = pC->pKVCur;

  if( pOp->opcode==OP_RowKey ){
    rc = sqlite4KVCursorKey(pCrsr, &pData, &nData);
    if( pOp->p5 ){
      nData = sqlite4VdbeShortKey(pData, nData, 1, 0);
3536
3537
3538
3539
3540
3541
3542

3543
3544
3545
3546
3547
3548
3549

  pKey = &aMem[pOp->p2];
  aIncr = &aMem[pOp->p3];
  nTotal = pOp->p4.i;
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->nullRow==0 );

  assert( pC->pKVCur!=0 );
  assert( pOp->p4type==P4_INT32 );

  rc = sqlite4KVCursorKey(pC->pKVCur, &pNew, &nNew);
  if( rc==SQLITE4_OK ){
    assert( pKey->flags & (MEM_Blob|MEM_Null) );
    if( pKey->flags & MEM_Blob ){







>







3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647

  pKey = &aMem[pOp->p2];
  aIncr = &aMem[pOp->p3];
  nTotal = pOp->p4.i;
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTableReg==0 );
  assert( pC->pKVCur!=0 );
  assert( pOp->p4type==P4_INT32 );

  rc = sqlite4KVCursorKey(pC->pKVCur, &pNew, &nNew);
  if( rc==SQLITE4_OK ){
    assert( pKey->flags & (MEM_Blob|MEM_Null) );
    if( pKey->flags & MEM_Blob ){
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
*/
case OP_Rowid: {                 /* out2-prerelease */
  VdbeCursor *pC;
  i64 v;
  const KVByteArray *aKey;
  KVSize nKey;
  int n;
  sqlite4_num vNum;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  rc = sqlite4VdbeCursorMoveto(pC);
  if( rc!=SQLITE4_OK ) break;
  assert( pC->sSeekKey.n==0 );

  if( pC->nullRow ){
    pOut->flags = MEM_Null;
    break;
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  }else if( pC->pVtabCursor ){
    pVtab = pC->pVtabCursor->pVtab;
    pModule = pVtab->pModule;
    assert( pModule->xRowid );
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    importVtabErrMsg(p, pVtab);
#endif /* SQLITE4_OMIT_VIRTUALTABLE */
  }else{
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      n = sqlite4GetVarint64(aKey, nKey, (sqlite4_uint64*)&v);
      n = sqlite4VdbeDecodeNumericKey(&aKey[n], nKey-n, &vNum);
      if( n==0 ) rc = SQLITE4_CORRUPT;
      v = sqlite4_num_to_int64(vNum,0);
    }
  }
  pOut->u.num = sqlite4_num_from_int64(v);
  break;
}

/* Opcode: NullRow P1 * * * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  pC->nullRow = 1;
  pC->rowChnged = 1;
  break;
}

/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.







<



<
<
|
>















|

<



















<







3685
3686
3687
3688
3689
3690
3691

3692
3693
3694


3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713

3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732

3733
3734
3735
3736
3737
3738
3739
*/
case OP_Rowid: {                 /* out2-prerelease */
  VdbeCursor *pC;
  i64 v;
  const KVByteArray *aKey;
  KVSize nKey;
  int n;


  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];


  assert( pC!=0 );
  assert( pC->pseudoTableReg==0 );
  if( pC->nullRow ){
    pOut->flags = MEM_Null;
    break;
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  }else if( pC->pVtabCursor ){
    pVtab = pC->pVtabCursor->pVtab;
    pModule = pVtab->pModule;
    assert( pModule->xRowid );
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    importVtabErrMsg(p, pVtab);
#endif /* SQLITE4_OMIT_VIRTUALTABLE */
  }else{
    rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      n = sqlite4GetVarint64(aKey, nKey, (sqlite4_uint64*)&v);
      n = sqlite4VdbeDecodeIntKey(&aKey[n], nKey-n, &v);
      if( n==0 ) rc = SQLITE4_CORRUPT;

    }
  }
  pOut->u.num = sqlite4_num_from_int64(v);
  break;
}

/* Opcode: NullRow P1 * * * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  pC->nullRow = 1;

  break;
}

/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
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
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
    pC->nullRow = 1;
    rc = SQLITE4_OK;
  }
  break;
}




/* Opcode: Insert 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.
**
** P3 can be either an integer or a blob.  If it is a blob then its value
** is used as-is as the KVStore key.  If P3 is an integer, then the KVStore
** key is constructed using P3 as the INTEGER PRIMARY KEY value.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).
*/

case OP_Insert: {
  VdbeCursor *pC;
  Mem *pKey;
  Mem *pData;
  int nKVKey;
  KVByteArray *pKVKey;
  KVByteArray aKey[24];
  

  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( pData==0 || (pData->flags & MEM_Blob) );

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

  if( pKey->flags & MEM_Int ){
    nKVKey = sqlite4PutVarint64(aKey, pC->iRoot);
    nKVKey += sqlite4VdbeEncodeIntKey(aKey+nKVKey, sqlite4VdbeIntValue(pKey));
    pKVKey = aKey;
  }else{
    nKVKey = pKey->n;
    pKVKey = pKey->z;
  }


  rc = sqlite4KVStoreReplace(
     pC->pKVCur->pStore,
     (u8 *)pKVKey, nKVKey,
     (u8 *)(pData ? pData->z : 0), (pData ? pData->n : 0)
  );
  pC->rowChnged = 1;

  break;
}

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







>
>
|





<
<
<
<



>
|



<
<
<
<







>



<
<
<
<
<
<
<
<
<
<



|


<







3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884




3885
3886
3887
3888
3889
3890
3891
3892




3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903










3904
3905
3906
3907
3908
3909

3910
3911
3912
3913
3914
3915
3916
    pC->nullRow = 1;
    rc = SQLITE4_OK;
  }
  break;
}


/* Opcode: SorterInsert P1 P2 P3
*/
/* 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.
**




** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).
*/
case OP_SorterInsert:
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,
     (u8 *)pKey->z, pKey->n,
     (u8 *)(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
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915

  rc = sqlite4KVCursorSeek(pC->pKVCur, (u8 *)pKey->z, pKey->n, 0);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorDelete(pC->pKVCur);
  }else if( rc==SQLITE4_NOTFOUND ){
    rc = SQLITE4_OK;
  }
  pC->rowChnged = 1;

  break;
}

/* Opcode: IdxRowkey P1 P2 P3 * *
**
** Cursor P1 points to an index entry. Extract the encoded primary key 
** fields from the entry. Then set output register P2 to a blob value
** containing the value P3 as a varint followed by the encoded PK
** fields.
**
** See also: Rowkey
*/
case OP_IdxRowkey: {              /* out2-prerelease */
  KVByteArray const *aKey;        /* Key data from cursor pIdx */
  KVSize nKey;                    /* Size of aKey[] in bytes */
  int nShort;                     /* Size of aKey[] without PK fields */
  KVByteArray *aPkKey;            /* Pointer to PK buffer */
  KVSize nPkKey;                  /* Size of aPkKey in bytes */
  int iRoot;
  VdbeCursor *pC;

  iRoot = pOp->p3;
  pOut = &aMem[pOp->p2];
  memAboutToChange(p, pOut);

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

  rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey);
  if( rc!=SQLITE4_OK ) break;

  nShort = sqlite4VdbeShortKey(aKey, nKey, 
      pC->pKeyInfo->nField - pC->pKeyInfo->nPK, 0
  );

  nPkKey = sqlite4VarintLen(iRoot) + nKey - nShort;
  if( nPkKey>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
    goto too_big;
  }

  rc = sqlite4VdbeMemGrow(pOut, nPkKey, 0);
  if( rc!=SQLITE4_OK ) break;
  aPkKey = pOut->z;
  putVarint32(aPkKey, iRoot);
  memcpy(&aPkKey[nPkKey - (nKey-nShort)], &aKey[nShort], nKey-nShort);
  pOut->type = SQLITE4_BLOB;
  pOut->n = nPkKey;
  MemSetTypeFlag(pOut, MEM_Blob);

  pOut->enc = SQLITE4_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  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







<




|

|
|
|
<

|

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







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

  rc = sqlite4KVCursorSeek(pC->pKVCur, (u8 *)pKey->z, pKey->n, 0);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorDelete(pC->pKVCur);
  }else if( rc==SQLITE4_NOTFOUND ){
    rc = SQLITE4_OK;
  }


  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
** the rowid of the table entry to which this index entry points.

**
** 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
Changes to src/vdbe.h.
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
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  int p3;             /* The third parameter */
  union {             /* fourth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */
    char *z;               /* Pointer to data for string (char array) types */
    sqlite4_num *pNum;     /* Used when p4type is P4_NUM */

    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    VTable *pVtab;         /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    int *ai;               /* Used when p4type is P4_INTARRAY */
    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
    Fts5Info *pFtsInfo;    /* Used when p4type is P4_FTS5INDEXINFO */
    int (*xAdvance)(VdbeCursor*);  /* Used with p4type==P4_ADVANCE */

  } p4;
#ifdef SQLITE4_DEBUG
  char *zComment;          /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;                 /* Number of times this instruction was executed */
  u64 cycles;              /* Total time spent executing this instruction */







|
>









|
>







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
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  int p3;             /* The third parameter */
  union {             /* fourth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */
    char *z;               /* Pointer to data for string (char array) types */
    i64 *pI64;             /* Used when p4type is P4_INT64 */
    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    VTable *pVtab;         /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    int *ai;               /* Used when p4type is P4_INTARRAY */
    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
    Fts5Info *pFtsInfo;    /* Used when p4type is P4_FTS5INDEXINFO */
    int (*xAdvance)(VdbeCursor*);
    sqlite4_num *pNum;     /* Used when p4type is P4_NUM */
  } p4;
#ifdef SQLITE4_DEBUG
  char *zComment;          /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;                 /* Number of times this instruction was executed */
  u64 cycles;              /* Total time spent executing this instruction */
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
  signed char p1;     /* First operand */
  signed char p2;     /* Second parameter (often the jump destination) */
  signed char p3;     /* Third parameter */
};
typedef struct VdbeOpList VdbeOpList;

/*
** Allowed values of VdbeOp.p4type.  All values are less than 1 so that
** they can be used unambiguously in the "length" parameter of various
** interfaces.
*/
#define P4_NOTUSED       0   /* The P4 parameter is not used */
#define P4_TRANSIENT     0   /* P4 is a pointer to a transient string */
#define P4_DYNAMIC     (-1)  /* Pointer to a string obtained from malloc() */
#define P4_STATIC      (-2)  /* Pointer to a static string */
#define P4_COLLSEQ     (-3)  /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF     (-4)  /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO     (-5)  /* P4 is a pointer to a KeyInfo structure */
#define P4_VDBEFUNC    (-6)  /* P4 is a pointer to a VdbeFunc structure */
#define P4_MEM         (-7)  /* P4 is a pointer to a Mem*    structure */

#define P4_VTAB        (-8)  /* P4 is a pointer to an sqlite4_vtab structure */


#define P4_NUM         (-9)  /* P4 is a pointer to an sqlite4_num structure */
#define P4_INT32      (-10)  /* P4 is a 32-bit signed integer */
#define P4_INTARRAY   (-11)  /* P4 is a vector of 32-bit integers */
#define P4_SUBPROGRAM (-12)  /* P4 is a pointer to a SubProgram structure */
#define P4_ADVANCE    (-13)  /* P4 is a pointer to BtreeNext() or BtreePrev() */
#define P4_FTS5INFO   (-14)  /* P4 points to an Fts5Info structure */


/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P4_KEYINFO_HANDOFF  (-124)
#define P4_KEYINFO_STATIC   (-125)

/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the 
** number of columns of data returned by the statement.
*/
#define COLNAME_NAME     0
#define COLNAME_DECLTYPE 1







|
<
<

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








|
|







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
  signed char p1;     /* First operand */
  signed char p2;     /* Second parameter (often the jump destination) */
  signed char p3;     /* Third parameter */
};
typedef struct VdbeOpList VdbeOpList;

/*
** Allowed values of VdbeOp.p4type


*/
#define P4_NOTUSED    0   /* The P4 parameter is not used */

#define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P4_STATIC   (-2)  /* Pointer to a static string */
#define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
#define P4_VDBEFUNC (-7)  /* P4 is a pointer to a VdbeFunc structure */
#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
#define P4_TRANSIENT  0   /* P4 is a pointer to a transient string */
#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite4_vtab structure */
#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite4_mprintf() */
#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */
#define P4_ADVANCE  (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
#define P4_FTS5INFO (-20) /* P4 points to an Fts5Info structure */
#define P4_NUM      (-21) /* P4 points to an Fts5Info structure */

/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P4_KEYINFO_HANDOFF (-16)
#define P4_KEYINFO_STATIC  (-17)

/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the 
** number of columns of data returned by the statement.
*/
#define COLNAME_NAME     0
#define COLNAME_DECLTYPE 1
212
213
214
215
216
217
218



219
220
221
222
223
224
225
sqlite4_value *sqlite4VdbeGetValue(Vdbe*, int, u8);
void sqlite4VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE4_OMIT_TRACE
  char *sqlite4VdbeExpandSql(Vdbe*, const char*);
#endif
sqlite4_value *sqlite4ColumnValue(sqlite4_stmt *pStmt, int iCol);




#ifndef SQLITE4_OMIT_TRIGGER
void sqlite4VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif


#ifndef NDEBUG
  void sqlite4VdbeComment(Vdbe*, const char*, ...);







>
>
>







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
sqlite4_value *sqlite4VdbeGetValue(Vdbe*, int, u8);
void sqlite4VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE4_OMIT_TRACE
  char *sqlite4VdbeExpandSql(Vdbe*, const char*);
#endif
sqlite4_value *sqlite4ColumnValue(sqlite4_stmt *pStmt, int iCol);

void sqlite4VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
UnpackedRecord *sqlite4VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);

#ifndef SQLITE4_OMIT_TRIGGER
void sqlite4VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif


#ifndef NDEBUG
  void sqlite4VdbeComment(Vdbe*, const char*, ...);
Changes to src/vdbeInt.h.
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
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;

/* Opaque type used by the explainer */
typedef struct Explain Explain;

/* Opaque type used by vdbecodec.c */
typedef struct RowDecoder RowDecoder;

/*
** A cursor is a pointer into a single database.
** The cursor can seek to an entry with a particular key, or
** loop over all entries.  You can also insert new
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct VdbeCursor {
  sqlite4 *db;          /* The connection that owns this cursor */
  KVCursor *pKVCur;     /* The cursor structure of the storage engine */
  KVStore *pTmpKV;      /* Separate file holding a temporary table */
  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
  int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
  int iRoot;            /* Root page of the table */

  int nField;           /* Number of fields in the header */


  Bool nullRow;         /* True if pointing to a row with no data */


  Bool rowChnged;       /* True if row has changed out from under pDecoder */


  i64 seqCount;         /* Sequence counter */

  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
  Fts5Cursor *pFts;     /* Fts5 cursor object (or NULL) */
  RowDecoder *pDecoder;              /* Decoder for row content */
  sqlite4_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
  const sqlite4_module *pModule;     /* Module for cursor pVtabCursor */
  sqlite4_buffer sSeekKey;           /* Key for deferred seek */
};

/* Methods for the VdbeCursor object */
void sqlite4VdbeFreeCursor(VdbeCursor*);
int sqlite4VdbeSeekEnd(VdbeCursor*, int);
int sqlite4VdbeNext(VdbeCursor*);
int sqlite4VdbePrevious(VdbeCursor*);
int sqlite4VdbeCursorMoveto(VdbeCursor *);


/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
** well as the current memory cell array and various other frame specific
** values stored in the Vdbe struct. When the sub-program is finished, 
** these values are copied back to the Vdbe from the VdbeFrame structure,







|












<
|




>

>
>

>
>
|
>
>

>


<
<
<
<
<

<
<
|
|
|
<
|







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
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;

/* Opaque type used by the explainer */
typedef struct Explain Explain;

/* Opaque type used by vdbecodec.c */
typedef struct ValueDecoder ValueDecoder;

/*
** A cursor is a pointer into a single database.
** The cursor can seek to an entry with a particular key, or
** loop over all entries.  You can also insert new
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct VdbeCursor {

  KVCursor *pKVCur;     /* The cursor structure of the backend */
  KVStore *pTmpKV;      /* Separate file holding a temporary table */
  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
  int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
  int iRoot;            /* Root page of the table */
  int pseudoTableReg;   /* Register holding pseudotable content. */
  int nField;           /* Number of fields in the header */
  Bool zeroed;          /* True if zeroed out and ready for reuse */
  Bool atFirst;         /* True if pointing to first entry */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool isTable;         /* True if a table requiring integer keys */
  Bool isIndex;         /* True if an index containing keys only - no data */
  Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
  sqlite4_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
  const sqlite4_module *pModule;     /* Module for cursor pVtabCursor */
  i64 seqCount;         /* Sequence counter */
  i64 movetoTarget;     /* Argument to the deferred move-to */
  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
  Fts5Cursor *pFts;     /* Fts5 cursor object (or NULL) */








  /* Result of last sqlite4-Moveto() done by an OP_NotExists or 
  ** OP_IsUnique opcode on this cursor. */
  int seekResult;

};

/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
** well as the current memory cell array and various other frame specific
** values stored in the Vdbe struct. When the sub-program is finished, 
** these values are copied back to the Vdbe from the VdbeFrame structure,
167
168
169
170
171
172
173

174
175
176
177
178
179
180
#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 */







>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#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 */
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
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/

void sqliteVdbePopStack(Vdbe*,int);
#if defined(SQLITE4_DEBUG) || defined(VDBE_PROFILE)
void sqlite4VdbePrintOp(FILE*, int, Op*);
#endif




void sqlite4VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite4VdbeDecoderCreate(
  sqlite4 *db,                /* The database connection */

  VdbeCursor *pCur,           /* Cursor associated with this decoder */
  KVCursor *pKVCur,           /* Alternative cursor if pCur is NULL */
  int mxCol,                  /* Maximum number of columns in aIn[] */
  RowDecoder **ppOut          /* The newly generated decoder object */
);
int sqlite4VdbeDecoderDestroy(RowDecoder *pDecoder);
int sqlite4VdbeDecoderGetColumn(
  RowDecoder *pDecoder,        /* The decoder for the whole string */
  int iVal,                    /* Index of the value to decode.  First is 0 */
  Mem *pDefault,               /* The default value.  Often NULL */
  Mem *pOut                    /* Write the result here */
);
int sqlite4VdbeEncodeData(
  sqlite4 *db,                /* The database connection */
  Mem *aIn,                   /* Array of values to encode */
  int *aPermute,              /* Permutation (or NULL) */
  int nIn,                    /* Number of entries in aIn[] */
  u8 **pzOut,                 /* The output data record */
  int *pnOut                  /* Bytes of content in pzOut */
);
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int nInTotal,                /* Number of values in complete key */
  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 nExtra                   /* Append extra bytes on end of key */
);
int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
int sqlite4VdbeDecodeNumericKey(const KVByteArray*, KVSize, sqlite4_num*);
int sqlite4VdbeShortKey(const u8 *, int, int, int *);
int sqlite4MemCompare(Mem*, Mem*, const CollSeq*,int*);
int sqlite4VdbeExec(Vdbe*);
int sqlite4VdbeList(Vdbe*);
int sqlite4VdbeHalt(Vdbe*);
int sqlite4VdbeChangeEncoding(Mem *, int);
int sqlite4VdbeMemTooBig(Mem*);







>




>
>
>
>


|

>
|
<

|

|
|
|







<
















|







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
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/
void sqlite4VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
#if defined(SQLITE4_DEBUG) || defined(VDBE_PROFILE)
void sqlite4VdbePrintOp(FILE*, int, Op*);
#endif
u32 sqlite4VdbeSerialTypeLen(u32);
u32 sqlite4VdbeSerialType(Mem*, int);
u32 sqlite4VdbeSerialPut(unsigned char*, int, Mem*, int);
u32 sqlite4VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite4VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite4VdbeCreateDecoder(
  sqlite4 *db,                /* The database connection */
  const unsigned char *aIn,   /* The input data blob */
  int nIn,                    /* Number of bytes in aIn[] */

  int mxCol,                  /* Maximum number of columns in aIn[] */
  ValueDecoder **ppOut        /* The newly generated decoder object */
);
int sqlite4VdbeDestroyDecoder(ValueDecoder *pDecoder);
int sqlite4VdbeDecodeValue(
  ValueDecoder *pDecoder,      /* The decoder for the whole string */
  int iVal,                    /* Index of the value to decode.  First is 0 */
  Mem *pDefault,               /* The default value.  Often NULL */
  Mem *pOut                    /* Write the result here */
);
int sqlite4VdbeEncodeData(
  sqlite4 *db,                /* The database connection */
  Mem *aIn,                   /* Array of values to encode */

  int nIn,                    /* Number of entries in aIn[] */
  u8 **pzOut,                 /* The output data record */
  int *pnOut                  /* Bytes of content in pzOut */
);
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int nInTotal,                /* Number of values in complete key */
  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 nExtra                   /* Append extra bytes on end of key */
);
int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
int sqlite4VdbeDecodeIntKey(const KVByteArray*, KVSize, sqlite4_int64*);
int sqlite4VdbeShortKey(const u8 *, int, int, int *);
int sqlite4MemCompare(Mem*, Mem*, const CollSeq*,int*);
int sqlite4VdbeExec(Vdbe*);
int sqlite4VdbeList(Vdbe*);
int sqlite4VdbeHalt(Vdbe*);
int sqlite4VdbeChangeEncoding(Mem *, int);
int sqlite4VdbeMemTooBig(Mem*);
420
421
422
423
424
425
426




427
428
429
430
431
432
433
const char *sqlite4OpcodeName(int);
int sqlite4VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite4VdbeCloseStatement(Vdbe *, int);
void sqlite4VdbeFrameDelete(VdbeFrame*);
int sqlite4VdbeFrameRestore(VdbeFrame *);
void sqlite4VdbeMemStoreType(Mem *pMem);
int sqlite4VdbeTransferError(Vdbe *p);




int sqlite4VdbeRollback(sqlite4 *db, int iLevel);
int sqlite4VdbeCommit(sqlite4 *db, int iLevel);

#ifdef SQLITE4_DEBUG
void sqlite4VdbeMemAboutToChange(Vdbe*,Mem*);
#endif








>
>
>
>







424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
const char *sqlite4OpcodeName(int);
int sqlite4VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite4VdbeCloseStatement(Vdbe *, int);
void sqlite4VdbeFrameDelete(VdbeFrame*);
int sqlite4VdbeFrameRestore(VdbeFrame *);
void sqlite4VdbeMemStoreType(Mem *pMem);
int sqlite4VdbeTransferError(Vdbe *p);
int sqlite4VdbeSeekEnd(VdbeCursor*, int);
int sqlite4VdbeNext(VdbeCursor*);
int sqlite4VdbePrevious(VdbeCursor*);

int sqlite4VdbeRollback(sqlite4 *db, int iLevel);
int sqlite4VdbeCommit(sqlite4 *db, int iLevel);

#ifdef SQLITE4_DEBUG
void sqlite4VdbeMemAboutToChange(Vdbe*,Mem*);
#endif

Changes to src/vdbeapi.c.
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
  return (int)sqlite4VdbeIntValue((Mem*)pVal);
}
sqlite4_int64 sqlite4_value_int64(sqlite4_value *pVal){
  return sqlite4VdbeIntValue((Mem*)pVal);
}
const char *sqlite4_value_text(sqlite4_value *pVal, int *pnByte){
  const char *zRet = (const char *)sqlite4ValueText(pVal, SQLITE4_UTF8);
  if( pnByte ) *pnByte = (zRet ? ((Mem *)pVal)->n : 0);
  return zRet;
}
#ifndef SQLITE4_OMIT_UTF16
const void *sqlite4_value_text16(sqlite4_value* pVal, int *pnByte){
  const void *pRet = sqlite4ValueText(pVal, SQLITE4_UTF16NATIVE);
  if( pnByte ) *pnByte = (pRet ? ((Mem *)pVal)->n : 0);
  return pRet;
}
const void *sqlite4_value_text16be(sqlite4_value *pVal, int *pnByte){
  const void *pRet = sqlite4ValueText(pVal, SQLITE4_UTF16BE);
  if( pnByte ) *pnByte = (pRet ? ((Mem *)pVal)->n : 0);
  return pRet;
}
const void *sqlite4_value_text16le(sqlite4_value *pVal, int *pnByte){
  const void *pRet = sqlite4ValueText(pVal, SQLITE4_UTF16LE);
  if( pnByte ) *pnByte = (pRet ? ((Mem *)pVal)->n : 0);
  return pRet;
}
#endif /* SQLITE4_OMIT_UTF16 */
int sqlite4_value_type(sqlite4_value* pVal){
  return pVal->type;
}








|





|




|




|







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
  return (int)sqlite4VdbeIntValue((Mem*)pVal);
}
sqlite4_int64 sqlite4_value_int64(sqlite4_value *pVal){
  return sqlite4VdbeIntValue((Mem*)pVal);
}
const char *sqlite4_value_text(sqlite4_value *pVal, int *pnByte){
  const char *zRet = (const char *)sqlite4ValueText(pVal, SQLITE4_UTF8);
  if( pnByte ) *pnByte = ((Mem *)pVal)->n;
  return zRet;
}
#ifndef SQLITE4_OMIT_UTF16
const void *sqlite4_value_text16(sqlite4_value* pVal, int *pnByte){
  const void *pRet = sqlite4ValueText(pVal, SQLITE4_UTF16NATIVE);
  if( pnByte ) *pnByte = ((Mem *)pVal)->n;
  return pRet;
}
const void *sqlite4_value_text16be(sqlite4_value *pVal, int *pnByte){
  const void *pRet = sqlite4ValueText(pVal, SQLITE4_UTF16BE);
  if( pnByte ) *pnByte = ((Mem *)pVal)->n;
  return pRet;
}
const void *sqlite4_value_text16le(sqlite4_value *pVal, int *pnByte){
  const void *pRet = sqlite4ValueText(pVal, SQLITE4_UTF16LE);
  if( pnByte ) *pnByte = ((Mem *)pVal)->n;
  return pRet;
}
#endif /* SQLITE4_OMIT_UTF16 */
int sqlite4_value_type(sqlite4_value* pVal){
  return pVal->type;
}

Changes to src/vdbeaux.c.
580
581
582
583
584
585
586

587

588
589
590
591
592
593




594
595
596
597
598
599
600
/*
** Delete a P4 value if necessary.
*/
static void freeP4(sqlite4 *db, int p4type, void *p4){
  if( p4 ){
    assert( db );
    switch( p4type ){

      case P4_NUM:

      case P4_DYNAMIC:
      case P4_KEYINFO:
      case P4_INTARRAY:
      case P4_KEYINFO_HANDOFF: {
        sqlite4DbFree(db, p4);
        break;




      }
      case P4_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
        freeEphemeralFunction(db, pVdbeFunc->pFunc);
        if( db->pnBytesFreed==0 ) sqlite4VdbeDeleteAuxData(pVdbeFunc, 0);
        sqlite4DbFree(db, pVdbeFunc);
        break;







>

>






>
>
>
>







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
/*
** Delete a P4 value if necessary.
*/
static void freeP4(sqlite4 *db, int p4type, void *p4){
  if( p4 ){
    assert( db );
    switch( p4type ){
      case P4_REAL:
      case P4_NUM:
      case P4_INT64:
      case P4_DYNAMIC:
      case P4_KEYINFO:
      case P4_INTARRAY:
      case P4_KEYINFO_HANDOFF: {
        sqlite4DbFree(db, p4);
        break;
      }
      case P4_MPRINTF: {
        if( db->pnBytesFreed==0 ) sqlite4_free(db->pEnv, p4);
        break;
      }
      case P4_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
        freeEphemeralFunction(db, pVdbeFunc->pFunc);
        if( db->pnBytesFreed==0 ) sqlite4VdbeDeleteAuxData(pVdbeFunc, 0);
        sqlite4DbFree(db, pVdbeFunc);
        break;
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
     || defined(VDBE_PROFILE) || defined(SQLITE4_DEBUG)
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
  char *zP4 = zTemp;
  assert( nTemp>=30 );
  switch( pOp->p4type ){
    case P4_KEYINFO_STATIC:
    case P4_KEYINFO: {
      int i, j;
      KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
      i = sqlite4_snprintf(zTemp, nTemp,
                 "keyinfo(%d,%d,%d", pKeyInfo->nField, pKeyInfo->nPK,
                 pKeyInfo->nData);
      for(j=0; j<pKeyInfo->nField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];
        if( pColl ){
          int n = sqlite4Strlen30(pColl->zName);
          if( i+n>nTemp-6 ){
            memcpy(&zTemp[i],",...",4);
            break;







|





|
<
<







843
844
845
846
847
848
849
850
851
852
853
854
855
856


857
858
859
860
861
862
863
     || defined(VDBE_PROFILE) || defined(SQLITE4_DEBUG)
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
  char *zP4 = zTemp;
  assert( nTemp>=20 );
  switch( pOp->p4type ){
    case P4_KEYINFO_STATIC:
    case P4_KEYINFO: {
      int i, j;
      KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
      i = sqlite4_snprintf(zTemp, nTemp, "keyinfo(%d", pKeyInfo->nField);


      for(j=0; j<pKeyInfo->nField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];
        if( pColl ){
          int n = sqlite4Strlen30(pColl->zName);
          if( i+n>nTemp-6 ){
            memcpy(&zTemp[i],",...",4);
            break;
879
880
881
882
883
884
885




886
887
888
889
890
891
892
893
894
895
896
897
898
899
      sqlite4_snprintf(zTemp, nTemp, "collseq(%.20s)", pColl->zName);
      break;
    }
    case P4_FUNCDEF: {
      FuncDef *pDef = pOp->p4.pFunc;
      sqlite4_snprintf(zTemp, nTemp, "%s(%d)", pDef->zName, pDef->nArg);
      break;




    }
    case P4_INT32: {
      sqlite4_snprintf(zTemp, nTemp, "%d", pOp->p4.i);
      break;
    }
    case P4_NUM: {
      sqlite4_num_to_text(*pOp->p4.pNum, zTemp, 0); 
      break;
    }
    case P4_MEM: {
      Mem *pMem = pOp->p4.pMem;
      if( pMem->flags & MEM_Str ){
        zP4 = pMem->z;
      }else if( pMem->flags & (MEM_Int|MEM_Real) ){







>
>
>
>





|
|







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
      sqlite4_snprintf(zTemp, nTemp, "collseq(%.20s)", pColl->zName);
      break;
    }
    case P4_FUNCDEF: {
      FuncDef *pDef = pOp->p4.pFunc;
      sqlite4_snprintf(zTemp, nTemp, "%s(%d)", pDef->zName, pDef->nArg);
      break;
    }
    case P4_INT64: {
      sqlite4_snprintf(zTemp, nTemp, "%lld", *pOp->p4.pI64);
      break;
    }
    case P4_INT32: {
      sqlite4_snprintf(zTemp, nTemp, "%d", pOp->p4.i);
      break;
    }
    case P4_REAL: {
      sqlite4_snprintf(zTemp, nTemp, "%.16g", *pOp->p4.pReal);
      break;
    }
    case P4_MEM: {
      Mem *pMem = pOp->p4.pMem;
      if( pMem->flags & MEM_Str ){
        zP4 = pMem->z;
      }else if( pMem->flags & (MEM_Int|MEM_Real) ){
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
    case P4_VTAB: {
      sqlite4_vtab *pVtab = pOp->p4.pVtab->pVtab;
      sqlite4_snprintf(zTemp, nTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      break;
    }
#endif
    case P4_INTARRAY: {
      int i, j, n, cSep = '(';
      i = sqlite4_snprintf(zTemp, nTemp, "intarray");
      n = pOp->opcode==OP_Permutation ? pOp->p1 : 0;
      for(j=0; j<n; j++){
        i += sqlite4_snprintf(zTemp+i, nTemp-i,"%c%d",cSep, pOp->p4.ai[j]);
        cSep = ',';
      }
      sqlite4_snprintf(zTemp+i, nTemp-i, ")");
      break;
    }
    case P4_SUBPROGRAM: {
      sqlite4_snprintf(zTemp, nTemp, "program");
      break;
    }
    case P4_ADVANCE: {
      zTemp[0] = 0;
      break;
    }
    default: {
      if( pOp->opcode==OP_Blob ){
        int n = pOp->p1*2+2;
        if( n>nTemp-2 ) n = nTemp-2;
        zTemp[0] = 'x';
        zTemp[1] = '\'';
        sqlite4BlobToHex((n-2)/2,pOp->p4.z,zTemp+2);
        zTemp[n] = '\'';
        zTemp[n+1] = 0;
      }else{
        zP4 = pOp->p4.z;
        if( zP4==0 ){
          zP4 = zTemp;
          zTemp[0] = 0;
        }
      }
    }
  }
  assert( zP4!=0 );
  return zP4;
}
#endif







<
|
<
<
<
<
<
<











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







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
    case P4_VTAB: {
      sqlite4_vtab *pVtab = pOp->p4.pVtab->pVtab;
      sqlite4_snprintf(zTemp, nTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      break;
    }
#endif
    case P4_INTARRAY: {

      sqlite4_snprintf(zTemp, nTemp, "intarray");






      break;
    }
    case P4_SUBPROGRAM: {
      sqlite4_snprintf(zTemp, nTemp, "program");
      break;
    }
    case P4_ADVANCE: {
      zTemp[0] = 0;
      break;
    }
    default: {









      zP4 = pOp->p4.z;
      if( zP4==0 ){
        zP4 = zTemp;
        zTemp[0] = 0;

      }
    }
  }
  assert( zP4!=0 );
  return zP4;
}
#endif
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981

#if defined(VDBE_PROFILE) || defined(SQLITE4_DEBUG)
/*
** Print a single opcode.  This routine is used for debugging only.
*/
void sqlite4VdbePrintOp(FILE *pOut, int pc, Op *pOp){
  char *zP4;
  char zPtr[150];
  static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
  if( pOut==0 ) pOut = stdout;
  zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
  fprintf(pOut, zFormat1, pc, 
      sqlite4OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
#ifdef SQLITE4_DEBUG
      pOp->zComment ? pOp->zComment : ""







|







958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

#if defined(VDBE_PROFILE) || defined(SQLITE4_DEBUG)
/*
** Print a single opcode.  This routine is used for debugging only.
*/
void sqlite4VdbePrintOp(FILE *pOut, int pc, Op *pOp){
  char *zP4;
  char zPtr[50];
  static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
  if( pOut==0 ) pOut = stdout;
  zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
  fprintf(pOut, zFormat1, pc, 
      sqlite4OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
#ifdef SQLITE4_DEBUG
      pOp->zComment ? pOp->zComment : ""
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
** allocated by the OP_Program opcode in sqlite4VdbeExec().
*/
void sqlite4VdbeFrameDelete(VdbeFrame *p){
  int i;
  Mem *aMem = VdbeFrameMem(p);
  VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
  for(i=0; i<p->nChildCsr; i++){
    sqlite4VdbeFreeCursor(apCsr[i]);
  }
  releaseMemArray(aMem, p->nChildMem);
  sqlite4DbFree(p->v->db, p);
}

#ifndef SQLITE4_OMIT_EXPLAIN
/*







|







1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
** allocated by the OP_Program opcode in sqlite4VdbeExec().
*/
void sqlite4VdbeFrameDelete(VdbeFrame *p){
  int i;
  Mem *aMem = VdbeFrameMem(p);
  VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
  for(i=0; i<p->nChildCsr; i++){
    sqlite4VdbeFreeCursor(p->v, apCsr[i]);
  }
  releaseMemArray(aMem, p->nChildMem);
  sqlite4DbFree(p->v->db, p);
}

#ifndef SQLITE4_OMIT_EXPLAIN
/*
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
    pMem++;

    pMem->flags = MEM_Int;
    pMem->u.num = sqlite4_num_from_int64(pOp->p3);         /* P3 */
    pMem->type = SQLITE4_INTEGER;
    pMem++;

    if( sqlite4VdbeMemGrow(pMem, 150, 0) ){                /* P4 */
      assert( p->db->mallocFailed );
      return SQLITE4_ERROR;
    }
    pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
    z = displayP4(pOp, pMem->z, 150);
    if( z!=pMem->z ){
      sqlite4VdbeMemSetStr(pMem, z, -1, SQLITE4_UTF8, 0, 0);
    }else{
      assert( pMem->z!=0 );
      pMem->n = sqlite4Strlen30(pMem->z);
      pMem->enc = SQLITE4_UTF8;
    }







|




|







1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
    pMem++;

    pMem->flags = MEM_Int;
    pMem->u.num = sqlite4_num_from_int64(pOp->p3);         /* P3 */
    pMem->type = SQLITE4_INTEGER;
    pMem++;

    if( sqlite4VdbeMemGrow(pMem, 32, 0) ){                 /* P4 */
      assert( p->db->mallocFailed );
      return SQLITE4_ERROR;
    }
    pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
    z = displayP4(pOp, pMem->z, 32);
    if( z!=pMem->z ){
      sqlite4VdbeMemSetStr(pMem, z, -1, SQLITE4_UTF8, 0, 0);
    }else{
      assert( pMem->z!=0 );
      pMem->n = sqlite4Strlen30(pMem->z);
      pMem->enc = SQLITE4_UTF8;
    }
1491
1492
1493
1494
1495
1496
1497


























1498
1499
1500
1501
1502
1503
1504
      p->aMem[n].flags = MEM_Invalid;
      p->aMem[n].db = db;
    }
  }
  p->explain = pParse->explain;
  sqlite4VdbeRewind(p);
}



























/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
int sqlite4VdbeFrameRestore(VdbeFrame *pFrame){







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







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
      p->aMem[n].flags = MEM_Invalid;
      p->aMem[n].db = db;
    }
  }
  p->explain = pParse->explain;
  sqlite4VdbeRewind(p);
}

/*
** Close a VDBE cursor and release all the resources that cursor 
** happens to hold.
*/
void sqlite4VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
  if( pCx==0 ){
    return;
  }
  sqlite4Fts5Close(pCx->pFts);
  if( pCx->pKVCur ){
    sqlite4KVCursorClose(pCx->pKVCur);
  }
  if( pCx->pTmpKV ){
    sqlite4KVStoreClose(pCx->pTmpKV);
  }
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if( pCx->pVtabCursor ){
    sqlite4_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
    const sqlite4_module *pModule = pCx->pModule;
    p->inVtabMethod = 1;
    pModule->xClose(pVtabCursor);
    p->inVtabMethod = 0;
  }
#endif
}

/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
int sqlite4VdbeFrameRestore(VdbeFrame *pFrame){
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
  p->nFrame = 0;

  if( p->apCsr ){
    int i;
    for(i=0; i<p->nCursor; i++){
      VdbeCursor *pC = p->apCsr[i];
      if( pC ){
        sqlite4VdbeFreeCursor(pC);
        p->apCsr[i] = 0;
      }
    }
  }
  if( p->aMem ){
    releaseMemArray(&p->aMem[1], p->nMem);
  }







|







1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
  p->nFrame = 0;

  if( p->apCsr ){
    int i;
    for(i=0; i<p->nCursor; i++){
      VdbeCursor *pC = p->apCsr[i];
      if( pC ){
        sqlite4VdbeFreeCursor(p, pC);
        p->apCsr[i] = 0;
      }
    }
  }
  if( p->aMem ){
    releaseMemArray(&p->aMem[1], p->nMem);
  }
2174
2175
2176
2177
2178
2179
2180














































2181
2182
2183
2184
2185
2186
2187
  return u.r;
}
# define swapMixedEndianFloat(X)  X = floatSwap(X)
#else
# define swapMixedEndianFloat(X)
#endif
















































/*
** This routine sets the value to be returned by subsequent calls to
** sqlite4_changes() on the database handle 'db'. 
*/
void sqlite4VdbeSetChanges(sqlite4 *db, int nChange){
  assert( sqlite4_mutex_held(db->mutex) );







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







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
  return u.r;
}
# define swapMixedEndianFloat(X)  X = floatSwap(X)
#else
# define swapMixedEndianFloat(X)
#endif


/*
** This routine is used to allocate sufficient space for an UnpackedRecord
** structure large enough to be used with sqlite4VdbeRecordUnpack() if
** the first argument is a pointer to KeyInfo structure pKeyInfo.
**
** The space is either allocated using sqlite4DbMallocRaw() or from within
** the unaligned buffer passed via the second and third arguments (presumably
** stack space). If the former, then *ppFree is set to a pointer that should
** be eventually freed by the caller using sqlite4DbFree(). Or, if the 
** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL
** before returning.
**
** If an OOM error occurs, NULL is returned.
*/
UnpackedRecord *sqlite4VdbeAllocUnpackedRecord(
  KeyInfo *pKeyInfo,              /* Description of the record */
  char *pSpace,                   /* Unaligned space available */
  int szSpace,                    /* Size of pSpace[] in bytes */
  char **ppFree                   /* OUT: Caller should free this pointer */
){
  UnpackedRecord *p;              /* Unpacked record to return */
  int nOff;                       /* Increment pSpace by nOff to align it */
  int nByte;                      /* Number of bytes required for *p */

  /* We want to shift the pointer pSpace up such that it is 8-byte aligned.
  ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift 
  ** it by.  If pSpace is already 8-byte aligned, nOff should be zero.
  */
  nOff = (8 - (SQLITE4_PTR_TO_INT(pSpace) & 7)) & 7;
  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
  if( nByte>szSpace+nOff ){
    p = (UnpackedRecord *)sqlite4DbMallocRaw(pKeyInfo->db, nByte);
    *ppFree = (char *)p;
    if( !p ) return 0;
  }else{
    p = (UnpackedRecord*)&pSpace[nOff];
    *ppFree = 0;
  }

  p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
  p->pKeyInfo = pKeyInfo;
  p->nField = pKeyInfo->nField + 1;
  return p;
}


/*
** This routine sets the value to be returned by subsequent calls to
** sqlite4_changes() on the database handle 'db'. 
*/
void sqlite4VdbeSetChanges(sqlite4 *db, int nChange){
  assert( sqlite4_mutex_held(db->mutex) );
Changes to src/vdbecodec.c.
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
** insertion and reading from the key/value storage engine.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** The decoder object.
**
** An instance of this object is used to extract individual columns (numbers,
** strings, blobs, or NULLs) from a row of a table or index.  Usually the
** content is extract from the value side of the key/value pair, though
** sometimes information might be taken from the key as well.
**
** When the VDBE needs to extract multiple columns from the same row, it will
** try to reuse a single decoder object.  The decoder, therefore, should attempt
** to cache any intermediate results that might be useful on later invocations.
*/
struct RowDecoder {
  sqlite4 *db;                /* The database connection */
  VdbeCursor *pCur;           /* The cursor for being decoded */
  KVCursor *pKVCur;           /* Alternative KVCursor if pCur is NULL */
  const KVByteArray *a;       /* Content to be decoded */
  const KVByteArray *aKey;    /* Key content */
  KVSize n;                   /* Bytes of content in a[] */
  KVSize nKey;                /* Bytes of key content */
  int mxCol;                  /* Maximum number of columns */
};

/*
** Create an object that can be used to decode fields of the data encoding.
**
** The aIn[] value must remain stable for the life of the decoder.
*/
int sqlite4VdbeDecoderCreate(
  sqlite4 *db,                /* The database connection */
  VdbeCursor *pCur,           /* The cursor associated with this decoder */
  KVCursor *pKVCur,           /* Alternative KVCursor */
  int mxCol,                  /* Maximum number of columns to ever decode */
  RowDecoder **ppOut          /* Return the answer here */
){
  RowDecoder *p;

  assert( pCur==0 || pKVCur==0 );
  assert( pCur!=0 || pKVCur!=0 );
  p = sqlite4DbMallocZero(db, sizeof(*p));
  *ppOut = p;
  if( p==0 ) return SQLITE4_NOMEM;
  p->db = db;
  p->pCur = pCur;
  p->pKVCur = pKVCur;
  p->mxCol = mxCol;
  return SQLITE4_OK;
}

/*
** Destroy a decoder object previously created
** using sqlite4VdbeCreateDecoder().
*/
int sqlite4VdbeDecoderDestroy(RowDecoder *p){
  if( p ){
    sqlite4DbFree(p->db, p);
  }
  return SQLITE4_OK;
}

/*
** Make sure the p->a and p->n fields are valid and current.
*/
static int decoderFetchData(RowDecoder *p){
  VdbeCursor *pCur = p->pCur;
  int rc;
  if( pCur==0 ){
    rc = sqlite4KVCursorData(p->pKVCur, 0, -1, &p->a, &p->n);
    return rc;
  }
  if( pCur->rowChnged ){
    p->a = 0;
    p->aKey = 0;
    pCur->rowChnged = 0;
  }
  if( p->a ) return SQLITE4_OK;
  rc = sqlite4VdbeCursorMoveto(pCur);
  if( rc ) return rc;
  if( pCur->nullRow ){
    p->a = 0;
    p->n = 0;
    return SQLITE4_OK;
  }
  assert( pCur->pKVCur!=0 );
  return sqlite4KVCursorData(pCur->pKVCur, 0, -1, &p->a, &p->n);
}

/*
** Make sure the p->aKey and p->nKey fields are valid and current.
*/
static int decoderFetchKey(RowDecoder *p){
  VdbeCursor *pCur = p->pCur;
  int rc;
  if( pCur==0 ){
    rc = sqlite4KVCursorKey(p->pKVCur, &p->aKey, &p->nKey);
    return rc;
  }
  assert( p->a!=0 );
  if( p->aKey ) return SQLITE4_OK;
  assert( pCur->pKVCur!=0 );
  return sqlite4KVCursorKey(pCur->pKVCur, &p->aKey, &p->nKey);
}

/*
** Decode a blob from a key.  The blob-key is in a[0] through a[n-1].
** xorMask is either 0x00 for ascending order or 0xff for descending.
** Store the blob in pOut.
*/
static int decoderMemSetFromBlob(
  const KVByteArray *a, KVSize n, /* The blob as a key */
  unsigned int xorMask,           /* 0x00 (ascending) or 0xff (descending) */
  Mem *pOut                       /* Write the blob here */
){
  int rc;
  unsigned int m = 0;
  int i, j, k;

  sqlite4VdbeMemSetStr(pOut, "", 0, 0, 0, 0);
  rc = sqlite4VdbeMemGrow(pOut, n, 0);
  if( rc==SQLITE4_OK ){
    i = 0;
    j = 0;
    k = 0;
    while( i<n ){
      m = (m<<7) | ((a[i++] ^ xorMask)&0x7f);
      j += 7;
      if( j>=8 ){
        pOut->z[k++] = (m>>(j-8))&0xff;
        j -= 8;
      }
    }
    if( j>0 ){
      pOut->z[k] = m<<(7-j);
    }
    pOut->n = k;
  }
  return rc;
}

/*
** Decode a numeric key encoding.  Return the number of bytes in the
** encoding on success.  On an error, return 0.
*/
int sqlite4VdbeDecodeNumericKey(
  const KVByteArray *aKey,       /* Input encoding */
  KVSize nKey,                   /* Number of bytes in aKey[] */
  sqlite4_num *pVal              /* Write the result here */
){
  unsigned int i, y;
  unsigned int xorMask = 0;
  short e;
  sqlite4_uint64 m;
  sqlite4_int64 eBig;
  KVByteArray aInvertedKey[4];

  pVal->approx = 0;
  pVal->sign = 0;
  if( nKey<1 ) return 0;
  switch( aKey[0] ){
    case 0x06:   /* NaN ascending */
    case 0xf9:   /* NaN descending */
      pVal->m = 0;
      pVal->e = 1000;
      return 1;

    case 0x07:   /* -inf ascending */
    case 0xf8:   /* -inf descending */
      pVal->m = 1;
      pVal->sign = 1;
      pVal->e = 1000;
      return 1;

    case 0x15:   /* zero ascending */
    case 0xea:   /* zero descending */
      pVal->m = 0;
      pVal->e = 0;
      return 1;

    case 0x23:   /* +inf ascending */
    case 0xdc:   /* +inf descending */
      pVal->m = 1;
      pVal->e = 1000;
      return 1;

    case 0x09:
    case 0x0a:
    case 0x0b:
    case 0x0c:
    case 0x0d:
    case 0x0e:
    case 0x0f:
    case 0x10:
    case 0x11:
    case 0x12:
    case 0x13:   /* -medium ascending */
      pVal->sign = 1;
      xorMask = 0xff;
      e = 0x13 - aKey[0];
      i = 1;
      break;

    case 0xf6:
    case 0xf5:
    case 0xf4:
    case 0xf3:
    case 0xf2:
    case 0xf1:
    case 0xf0:
    case 0xef:
    case 0xee:
    case 0xed:
    case 0xec:   /* -medium descending */
      pVal->sign = 1;
      e = aKey[0] - 0xec;
      i = 1;
      break;

    case 0x17:
    case 0x18:
    case 0x19:
    case 0x1a:
    case 0x1b:
    case 0x1c:
    case 0x1d:
    case 0x1e:
    case 0x1f:
    case 0x20:
    case 0x21:   /* +medium ascending */
      e = aKey[0] - 0x17;
      i = 1;
      break;

    case 0xe8:
    case 0xe7:
    case 0xe6:
    case 0xe5:
    case 0xe4:
    case 0xe3:
    case 0xe2:
    case 0xe1:
    case 0xe0:
    case 0xdf:
    case 0xde:   /* +medium descending */
      e = 0xe8 - aKey[0];
      xorMask = 0xff;
      i = 1;
      break;

    case 0x14:   /* -small ascending */
    case 0xe9:   /* +small descending */
      i = 1 + sqlite4GetVarint64(aKey+1, 2, &eBig);
      e = (short)-eBig;
      xorMask = 0xff;
      break;

    case 0x16:   /* +small ascending */
    case 0xeb:   /* -small descending */
      aInvertedKey[0] = aKey[1] ^ 0xff;
      aInvertedKey[1] = aKey[2] ^ 0xff;
      i = 1 + sqlite4GetVarint64(aInvertedKey, 2, &eBig);
      e = (short)-eBig;
      break;

    case 0x08:   /* -large ascending */
    case 0xdd:   /* +large descending */
      aInvertedKey[0] = aKey[1] ^ 0xff;
      aInvertedKey[1] = aKey[2] ^ 0xff;
      i = 1 + sqlite4GetVarint64(aInvertedKey, 2, &eBig);
      e = (short)eBig;
      xorMask = 0xff;
      break;

    case 0x22:   /* +large ascending */
    case 0xf7:   /* -large descending */
      i = 1 + sqlite4GetVarint64(aKey+1, 2, &eBig);
      e = (short)eBig;
      break;

    default:
      return 0;
  }
  m = 0;
  do{
    y = aKey[i++] ^ xorMask;
    m = m*100 + y/2;
    e--;
  }while( y & 1 );
  if( m==0 ) return 0;

  pVal->m = m;
  pVal->e = 2*e;
  return i;
}

/*
** This is a private method for the RowDecoder object.
**
** Attempt to extract a single column value from the key of the current
** key/value pair.  If beginning of the value is iOfst bytes from the beginning
** of the key.  If affReal is true, then force numeric values to be floating
** point.  Write the result in pOut.  Or return non-zero if there is an
** error.
*/
static int decoderFromKey(
  RowDecoder *p,           /* The current key/value pair */
  int affReal,             /* True to coerce numbers to floating point */
  sqlite4_int64 iOfst,     /* Offset of value in the key */
  Mem *pOut                /* Write the results here */
){
  int rc;
  KVSize i;
  KVSize n;
  const KVByteArray *a;
  char *z;

  if( iOfst<0 ){
    return SQLITE4_CORRUPT_BKPT;
  }
  rc = decoderFetchKey(p);
  if( rc ) return rc;
  if( iOfst>=p->nKey ){
    return SQLITE4_CORRUPT_BKPT;
  }
  a = p->aKey;
  n = p->nKey;
  switch( a[iOfst++] ){
    case 0x05: case 0xFA:       /* NULL */
    case 0x06: case 0xF9: {     /* NaN */
      sqlite4VdbeMemSetNull(pOut);
      break;
    }

    case 0x24: {                /* Text (ascending index) */
      for(i=iOfst; i<n && a[i]!=0; i++){}
      rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst], i-iOfst,
                                SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      break;
    }
    case 0xDB: {                /* Text (descending index) */
      for(i=iOfst; i<n && a[i]!=0xFF; i++){}
      rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst+1], n = i - iOfst,
                                SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      if( rc==SQLITE4_OK ){
        z = pOut->z;
        for(i=n-1; i>=0; i--) *(z++) ^= 0xFF;
      }
      break;
    }

    case 0x25: {                /* Blob (ascending index) */
      for(i=iOfst; i<n && a[i]!=0; i++){}
      rc = decoderMemSetFromBlob(&a[iOfst], i-iOfst, 0x00, pOut);
      break;
    }
    case 0xDA: {                /* Blob (descending index) */
      for(i=iOfst; i<n && a[i]!=0xFF; i++){}
      rc = decoderMemSetFromBlob(&a[iOfst], i-iOfst, 0xFF, pOut);
      break;
    }

    case 0x26: {                /* Blob-final (ascending) */
      rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst], n-iOfst, 0,
                                SQLITE4_TRANSIENT, 0);
      break;
    }
    case 0xD9: {                /* Blob-final (descending) */
      rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst], n-iOfst,
                                SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      if( rc==SQLITE4_OK ){
        z = pOut->z;
        for(i=n-iOfst; i>0; i--) *(z++) ^= 0xFF;
      }
      break;
    }
    default: {
      sqlite4_num v;
      i = sqlite4VdbeDecodeNumericKey(a+iOfst-1, n-iOfst+1, &v);
      if( i==0 ){
        rc = SQLITE4_CORRUPT_BKPT;
      }else{
        sqlite4VdbeMemSetNum(pOut, v, affReal ? MEM_Real : MEM_Int);
        rc = SQLITE4_OK;
      }
      break;
    }
  };
  return rc;
}

/*
** Decode a single column from a key/value pair taken from the storage
** engine.  The key/value pair to be decoded is the one that the VdbeCursor
** or KVCursor is currently pointing to.
**
** iVal is the column index of the value.  0 is the first column of the
** value.  If N is the number of columns in the value and iVal>=N then
** the result is pDefault.  Write the result into pOut.  Return SQLITE4_OK
** on success or an appropriate error code on failure.
**
** The key is referenced only if the iVal-th column in the value is either
** the 22 or 23 header code which indicates that the value is stored in the
** key instead.
*/
int sqlite4VdbeDecoderGetColumn(
  RowDecoder *p,             /* The decoder for the whole string */
  int iVal,                    /* Index of the value to decode.  First is 0 */
  Mem *pDefault,               /* The default value.  Often NULL */
  Mem *pOut                    /* Write the result here */
){
  u32 size;                    /* Size of a field */
  sqlite4_uint64 ofst;         /* Offset to the payload */
  sqlite4_uint64 type;         /* Datatype */
  sqlite4_uint64 subtype;      /* Subtype for a typed blob */
  int cclass;                  /* class of content */
  int n;                       /* Offset into the header */
  int i;                       /* Loop counter */
  int sz;                      /* Size of a varint */
  int endHdr;                  /* First byte past header */
  int rc;                      /* Return code */

  sqlite4VdbeMemSetNull(pOut);
  assert( iVal<=p->mxCol );
  rc = decoderFetchData(p);
  if( rc ) return rc;
  if( p->a==0 ) return SQLITE4_OK;
  n = sqlite4GetVarint64(p->a, p->n, &ofst);
  if( n==0 ) return SQLITE4_CORRUPT;
  ofst += n;
  endHdr = ofst;
  if( endHdr>p->n ) return SQLITE4_CORRUPT;
  for(i=0; i<=iVal && n<endHdr; i++){
    sz = sqlite4GetVarint64(p->a+n, p->n-n, &type);
    if( sz==0 ) return SQLITE4_CORRUPT;
    n += sz;
    if( type>=22 ){  /* STRING, BLOB, KEY, and TYPED */
      cclass = (type-22)%4;
      if( cclass==2 ){
        size = 0;  /* KEY */
      }else{
        size = (type-22)/4;
        if( cclass==3 ){  /* The TYPED header code */
          sz = sqlite4GetVarint64(p->a+n, p->n-n, &subtype);
          if( sz==0 ) return SQLITE4_CORRUPT;
          n += sz;
        }
      }

    }else if( type<=2 ){  /* NULL, ZERO, and ONE */
      size = 0;
    }else if( type<=10 ){ /* INT */
      size = type - 2;
    }else{
      assert( type>=11 && type<=21 );  /* NUM */
      size = type - 9;
    }
    if( i<iVal ){
      ofst += size;
    }else if( type==0 ){
      /* no-op */
    }else if( type<=2 ){







<
<
<
<
<
<
<
<
<

|

<
<
|
<
|
<








|

|
|
|
|

|

<
<




|
|








|







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

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













<



<
<
<









|
|

<
<
<
<
|
|
|
|
<
>
|

|


<







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
** insertion and reading from the key/value storage engine.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** The decoder object.









*/
struct ValueDecoder {
  sqlite4 *db;                /* The database connection */


  const u8 *a;                /* Content to be decoded */

  int n;                      /* Bytes of content in a[] */

  int mxCol;                  /* Maximum number of columns */
};

/*
** Create an object that can be used to decode fields of the data encoding.
**
** The aIn[] value must remain stable for the life of the decoder.
*/
int sqlite4VdbeCreateDecoder(
  sqlite4 *db,                /* The database connection */
  const unsigned char *aIn,   /* The input data blob */
  int nIn,                    /* Number of bytes in aIn[] */
  int mxCol,                  /* Maximum number of columns in aIn[] */
  ValueDecoder **ppOut        /* The newly generated decoder object */
){
  ValueDecoder *p;



  p = sqlite4DbMallocZero(db, sizeof(*p));
  *ppOut = p;
  if( p==0 ) return SQLITE4_NOMEM;
  p->db = db;
  p->a = aIn;
  p->n = nIn;
  p->mxCol = mxCol;
  return SQLITE4_OK;
}

/*
** Destroy a decoder object previously created
** using sqlite4VdbeCreateDecoder().
*/
int sqlite4VdbeDestroyDecoder(ValueDecoder *p){
  if( p ){
    sqlite4DbFree(p->db, p);
  }
  return SQLITE4_OK;
}

/*

























** Decode a single value from a data string.


*/

























































































































































































































































































































int sqlite4VdbeDecodeValue(
  ValueDecoder *p,             /* The decoder for the whole string */
  int iVal,                    /* Index of the value to decode.  First is 0 */
  Mem *pDefault,               /* The default value.  Often NULL */
  Mem *pOut                    /* Write the result here */
){
  u32 size;                    /* Size of a field */
  sqlite4_uint64 ofst;         /* Offset to the payload */
  sqlite4_uint64 type;         /* Datatype */
  sqlite4_uint64 subtype;      /* Subtype for a typed blob */
  int cclass;                  /* class of content */
  int n;                       /* Offset into the header */
  int i;                       /* Loop counter */
  int sz;                      /* Size of a varint */
  int endHdr;                  /* First byte past header */


  sqlite4VdbeMemSetNull(pOut);
  assert( iVal<=p->mxCol );



  n = sqlite4GetVarint64(p->a, p->n, &ofst);
  if( n==0 ) return SQLITE4_CORRUPT;
  ofst += n;
  endHdr = ofst;
  if( endHdr>p->n ) return SQLITE4_CORRUPT;
  for(i=0; i<=iVal && n<endHdr; i++){
    sz = sqlite4GetVarint64(p->a+n, p->n-n, &type);
    if( sz==0 ) return SQLITE4_CORRUPT;
    n += sz;
    if( type>=22 ){
      cclass = (type-22)%3;
      if( cclass==2 ){




         sz = sqlite4GetVarint64(p->a+n, p->n-n, &subtype);
         if( sz==0 ) return SQLITE4_CORRUPT;
         n += sz;
      }

      size = (type-22)/3;
    }else if( type<=2 ){
      size = 0;
    }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 ){
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

      num.m = x;
      num.e = (e >> 2);
      if( e & 0x02 ) num.e = -1 * num.e;
      if( e & 0x01 ) num.sign = 1;
      pOut->u.num = num;
      MemSetTypeFlag(pOut, MEM_Real);

    }else if( cclass==0 ){
      if( size==0 ){
        sqlite4VdbeMemSetStr(pOut, "", 0, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      }else if( p->a[ofst]>0x02 ){
        sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size, 
                             SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      }else{
        static const u8 enc[] = {SQLITE4_UTF8,SQLITE4_UTF16LE,SQLITE4_UTF16BE };
        sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst+1), size-1, 
                             enc[p->a[ofst]], SQLITE4_TRANSIENT, 0);
      }
    }else if( cclass==2 ){
      unsigned int k = (type - 24)/4;
      return decoderFromKey(p, (k&1)!=0, k/2, pOut);
    }else{
      sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size, 0,
                           SQLITE4_TRANSIENT, 0);
      pOut->enc = ENC(p->db);
    }
  }
  testcase( i==iVal );
  testcase( i==iVal+1 );
  if( i<=iVal ){
    if( pDefault ){
      sqlite4VdbeMemShallowCopy(pOut, pDefault, MEM_Static);







>











<
<
<



<







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

      num.m = x;
      num.e = (e >> 2);
      if( e & 0x02 ) num.e = -1 * num.e;
      if( e & 0x01 ) num.sign = 1;
      pOut->u.num = num;
      MemSetTypeFlag(pOut, MEM_Real);

    }else if( cclass==0 ){
      if( size==0 ){
        sqlite4VdbeMemSetStr(pOut, "", 0, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      }else if( p->a[ofst]>0x02 ){
        sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size, 
                             SQLITE4_UTF8, SQLITE4_TRANSIENT, 0);
      }else{
        static const u8 enc[] = {SQLITE4_UTF8,SQLITE4_UTF16LE,SQLITE4_UTF16BE };
        sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst+1), size-1, 
                             enc[p->a[ofst]], SQLITE4_TRANSIENT, 0);
      }



    }else{
      sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size, 0,
                           SQLITE4_TRANSIENT, 0);

    }
  }
  testcase( i==iVal );
  testcase( i==iVal+1 );
  if( i<=iVal ){
    if( pDefault ){
      sqlite4VdbeMemShallowCopy(pOut, pDefault, MEM_Static);
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
    x = 127;
    while( v>x && n<8 ){ n++; x *= 256; }
  }
  return n;
}

/*
** Encode nIn values from array aIn[] using the data encoding. If argument
** aPermute[] is NULL, then the nIn elements are elements 0, 1 ... (nIn-1)
** of the array. Otherwise, aPermute[0], aPermute[1] ... aPermute[nIn-1].
**
** Assume that affinity has already been applied to all elements of the
** input array aIn[].
**
** Space to hold the record is obtained from sqlite4DbMalloc() and should
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
int sqlite4VdbeEncodeData(
  sqlite4 *db,                /* The database connection */
  Mem *aIn,                   /* Array of values to encode */
  int *aPermute,              /* Permutation or NULL (see above) */
  int nIn,                    /* Number of entries in aIn[] */
  u8 **pzOut,                 /* The output data record */
  int *pnOut                  /* Bytes of content in pzOut */
){
  int i, j;
  int rc = SQLITE4_OK;
  int nHdr;







|
<
<










<







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
    x = 127;
    while( v>x && n<8 ){ n++; x *= 256; }
  }
  return n;
}

/*
** Encode 1 or more values using the data encoding.


**
** Assume that affinity has already been applied to all elements of the
** input array aIn[].
**
** Space to hold the record is obtained from sqlite4DbMalloc() and should
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
int sqlite4VdbeEncodeData(
  sqlite4 *db,                /* The database connection */
  Mem *aIn,                   /* Array of values to encode */

  int nIn,                    /* Number of entries in aIn[] */
  u8 **pzOut,                 /* The output data record */
  int *pnOut                  /* Bytes of content in pzOut */
){
  int i, j;
  int rc = SQLITE4_OK;
  int nHdr;
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
  aOut = sqlite4DbMallocZero(db, (nIn+1)*9);
  if( aOut==0 ){
    rc = SQLITE4_NOMEM;
    goto vdbeEncodeData_error;
  }
  nOut = 9;
  for(i=0; i<nIn; i++){
    Mem *pIn = &aIn[ aPermute ? aPermute[i] : i ];
    int flags = pIn->flags;
    if( flags & MEM_Null ){
      aOut[nOut++] = 0;
    }else if( flags & MEM_Int ){
      i64 i1;
      i1 = sqlite4_num_to_int64(pIn->u.num, 0);
      n = significantBytes(i1);
      aOut[nOut++] = n+2;
      nPayload += n;
      aAux[i].n = n;
    }else if( flags & MEM_Real ){
      sqlite4_num *p = &pIn->u.num;
      int e;
      assert( p->sign==0 || p->sign==1 );
      if( p->e<0 ){
        e = (p->e*-4) + 2 + p->sign;
      }else{
        e = (p->e*4) + p->sign;
      }
      n = sqlite4PutVarint64(aAux[i].z, (sqlite4_uint64)e);
      n += sqlite4PutVarint64(aAux[i].z+n, p->m);
      aAux[i].n = n;
      aOut[nOut++] = n+9;
      nPayload += n;
    }else if( flags & MEM_Str ){
      n = pIn->n;
      if( n && (encoding!=SQLITE4_UTF8 || pIn->z[0]<3) ) n++;
      nPayload += n;
      nOut += sqlite4PutVarint64(aOut+nOut, 22+4*(sqlite4_int64)n);
    }else{
      n = pIn->n;
      assert( flags & MEM_Blob );
      nPayload += n;
      nOut += sqlite4PutVarint64(aOut+nOut, 23+4*(sqlite4_int64)n);
    }
  }
  nHdr = nOut - 9;
  n = sqlite4PutVarint64(aOut, nHdr);
  for(i=n, j=9; j<nOut; j++) aOut[i++] = aOut[j];
  nOut = i;
  aOut = sqlite4DbReallocOrFree(db, aOut, nOut + nPayload);
  if( aOut==0 ){ rc = SQLITE4_NOMEM; goto vdbeEncodeData_error; }
  for(i=0; i<nIn; i++){
    Mem *pIn = &aIn[ aPermute ? aPermute[i] : i ];
    int flags = pIn->flags;
    if( flags & MEM_Null ){
      /* No content */
    }else if( flags & MEM_Int ){
      sqlite4_int64 v;
      v = sqlite4_num_to_int64(pIn->u.num, 0);
      n = aAux[i].n;
      aOut[nOut+(--n)] = v & 0xff;
      while( n ){
        v >>= 8;
        aOut[nOut+(--n)] = v & 0xff;
      }
      nOut += aAux[i].n;
    }else if( flags & MEM_Real ){
      memcpy(aOut+nOut, aAux[i].z, aAux[i].n);
      nOut += aAux[i].n;
    }else if( flags & MEM_Str ){
      n = pIn->n;
      if( n ){
        if( encoding==SQLITE4_UTF16LE ) aOut[nOut++] = 1;
        else if( encoding==SQLITE4_UTF16BE ) aOut[nOut++] = 2;
        else if( pIn->z[0]<3 ) aOut[nOut++] = 0;
        memcpy(aOut+nOut, pIn->z, n);
        nOut += n;
      }
    }else{
      assert( flags & MEM_Blob );
      memcpy(aOut+nOut, pIn->z, pIn->n);
      nOut += pIn->n;
    }
  }

  *pzOut = aOut;
  *pnOut = nOut;
  sqlite4StackFree(db, aAux);
  return SQLITE4_OK;







<
|




|





|













|
|

|

|


|









<
|




|











|



|
|




|
|







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
  aOut = sqlite4DbMallocZero(db, (nIn+1)*9);
  if( aOut==0 ){
    rc = SQLITE4_NOMEM;
    goto vdbeEncodeData_error;
  }
  nOut = 9;
  for(i=0; i<nIn; i++){

    int flags = aIn[i].flags;
    if( flags & MEM_Null ){
      aOut[nOut++] = 0;
    }else if( flags & MEM_Int ){
      i64 i1;
      i1 = sqlite4_num_to_int64(aIn[i].u.num, 0);
      n = significantBytes(i1);
      aOut[nOut++] = n+2;
      nPayload += n;
      aAux[i].n = n;
    }else if( flags & MEM_Real ){
      sqlite4_num *p = &aIn[i].u.num;
      int e;
      assert( p->sign==0 || p->sign==1 );
      if( p->e<0 ){
        e = (p->e*-4) + 2 + p->sign;
      }else{
        e = (p->e*4) + p->sign;
      }
      n = sqlite4PutVarint64(aAux[i].z, (sqlite4_uint64)e);
      n += sqlite4PutVarint64(aAux[i].z+n, p->m);
      aAux[i].n = n;
      aOut[nOut++] = n+9;
      nPayload += n;
    }else if( flags & MEM_Str ){
      n = aIn[i].n;
      if( n && (encoding!=SQLITE4_UTF8 || aIn[i].z[0]<2) ) n++;
      nPayload += n;
      nOut += sqlite4PutVarint64(aOut+nOut, 22+3*(sqlite4_int64)n);
    }else{
      n = aIn[i].n;
      assert( flags & MEM_Blob );
      nPayload += n;
      nOut += sqlite4PutVarint64(aOut+nOut, 23+3*(sqlite4_int64)n);
    }
  }
  nHdr = nOut - 9;
  n = sqlite4PutVarint64(aOut, nHdr);
  for(i=n, j=9; j<nOut; j++) aOut[i++] = aOut[j];
  nOut = i;
  aOut = sqlite4DbReallocOrFree(db, aOut, nOut + nPayload);
  if( aOut==0 ){ rc = SQLITE4_NOMEM; goto vdbeEncodeData_error; }
  for(i=0; i<nIn; i++){

    int flags = aIn[i].flags;
    if( flags & MEM_Null ){
      /* No content */
    }else if( flags & MEM_Int ){
      sqlite4_int64 v;
      v = sqlite4_num_to_int64(aIn[i].u.num, 0);
      n = aAux[i].n;
      aOut[nOut+(--n)] = v & 0xff;
      while( n ){
        v >>= 8;
        aOut[nOut+(--n)] = v & 0xff;
      }
      nOut += aAux[i].n;
    }else if( flags & MEM_Real ){
      memcpy(aOut+nOut, aAux[i].z, aAux[i].n);
      nOut += aAux[i].n;
    }else if( flags & MEM_Str ){
      n = aIn[i].n;
      if( n ){
        if( encoding==SQLITE4_UTF16LE ) aOut[nOut++] = 1;
        else if( encoding==SQLITE4_UTF16BE ) aOut[nOut++] = 2;
        else if( aIn[i].z[0]<2 ) aOut[nOut++] = 0;
        memcpy(aOut+nOut, aIn[i].z, n);
        nOut += n;
      }
    }else{
      assert( flags & MEM_Blob );
      memcpy(aOut+nOut, aIn[i].z, aIn[i].n);
      nOut += aIn[i].n;
    }
  }

  *pzOut = aOut;
  *pnOut = nOut;
  sqlite4StackFree(db, aAux);
  return SQLITE4_OK;
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
}

/*
** Write value num into buffer p using the key encoding.
*/
static void encodeNumericKey(KeyEncoder *p, sqlite4_num num){
  if( num.m==0 ){

    if( sqlite4_num_isnan(num) ){
      p->aOut[p->nOut++] = 0x06;  /* NaN */
    }else{
      p->aOut[p->nOut++] = 0x15;  /* Numeric zero */
    }
  }else if( sqlite4_num_isinf(num) ){
    p->aOut[p->nOut++] = num.sign ? 0x07 : 0x23;  /* Neg and Pos infinity */
  }else{
    int e;
    u64 m;
    int iDigit = 0;
    u8 aDigit[12];







>
|
|
<
<
<







351
352
353
354
355
356
357
358
359
360



361
362
363
364
365
366
367
}

/*
** Write value num into buffer p using the key encoding.
*/
static void encodeNumericKey(KeyEncoder *p, sqlite4_num num){
  if( num.m==0 ){
    p->aOut[p->nOut++] = 0x15;  /* Numeric zero */
  }else if( sqlite4_num_isnan(num) ){
    p->aOut[p->nOut++] = 0x06;  /* NaN */



  }else if( sqlite4_num_isinf(num) ){
    p->aOut[p->nOut++] = num.sign ? 0x07 : 0x23;  /* Neg and Pos infinity */
  }else{
    int e;
    u64 m;
    int iDigit = 0;
    u8 aDigit[12];
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772

    while( m ){
      aDigit[iDigit++] = (m % 100);
      m = m / 100;
    }
    e = (iDigit + (e/2));

    if( e>=11 ){                /* Large value */
      if( num.sign==0 ){
        p->aOut[p->nOut++] = 0x22;
        putVarint64(p, e, 0);
      }else{
        p->aOut[p->nOut++] = 0x08;
        putVarint64(p, e, 1);
      }







|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

    while( m ){
      aDigit[iDigit++] = (m % 100);
      m = m / 100;
    }
    e = (iDigit + (e/2));

    if( e>11 ){                 /* Large value */
      if( num.sign==0 ){
        p->aOut[p->nOut++] = 0x22;
        putVarint64(p, e, 0);
      }else{
        p->aOut[p->nOut++] = 0x08;
        putVarint64(p, e, 1);
      }
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865

    /* Write the encoded key to the output buffer. */
    if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE4_NOMEM;
    p->aOut[p->nOut++] = 0x24;   /* Text */
    if( pColl==0 || pColl->xMkKey==0 ){
      const char *z = (const char *)sqlite4ValueText(pMem, SQLITE4_UTF8);
      if( z ){
        const char *zCsr = z;
        const char *zEnd = &z[pMem->n];
        while( *zCsr && zCsr<zEnd ) zCsr++;
        memcpy(p->aOut+p->nOut, z, (zCsr-z));
        p->nOut += (zCsr-z);
      }
    }else{
      int rc;                     /* xMkKey() return code */
      int nReq;                   /* Space required by xMkKey() */
      int nSpc;                   /* Space available */

      nSpc = p->nAlloc-p->nOut;







<
<
<
|
|







473
474
475
476
477
478
479



480
481
482
483
484
485
486
487
488

    /* Write the encoded key to the output buffer. */
    if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE4_NOMEM;
    p->aOut[p->nOut++] = 0x24;   /* Text */
    if( pColl==0 || pColl->xMkKey==0 ){
      const char *z = (const char *)sqlite4ValueText(pMem, SQLITE4_UTF8);
      if( z ){



        memcpy(p->aOut+p->nOut, z, pMem->n);
        p->nOut += pMem->n;
      }
    }else{
      int rc;                     /* xMkKey() return code */
      int nReq;                   /* Space required by xMkKey() */
      int nSpc;                   /* Space available */

      nSpc = p->nAlloc-p->nOut;
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
    assert( flags & MEM_Blob );
    n = pMem->n;
    a = (u8*)pMem->z;
    s = 1;
    t = 0;
    if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE4_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{
        p->aOut[p->nOut++] = 0x80 | x;







|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    assert( flags & MEM_Blob );
    n = pMem->n;
    a = (u8*)pMem->z;
    s = 1;
    t = 0;
    if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE4_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{
        p->aOut[p->nOut++] = 0x80 | x;
1049
1050
1051
1052
1053
1054
1055

















































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
























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    sqlite4DbFree(db, x.aOut);
  }else{
    *paOut = x.aOut;
    *pnOut = x.nOut;
  }
  return rc;
}

/*
** Decode an integer key encoding.  Return the number of bytes in the
** encoding on success.  On an error, return 0.
*/
int sqlite4VdbeDecodeIntKey(
  const KVByteArray *aKey,       /* Input encoding */
  KVSize nKey,                   /* Number of bytes in aKey[] */
  sqlite4_int64 *pVal            /* Write the result here */
){
  int isNeg;
  int e, x;
  int i;
  sqlite4_int64 m;
  KVByteArray aBuf[12];

  if( nKey<2 ) return 0;
  if( nKey>sizeof(aBuf) ) nKey = sizeof(aBuf);
  x = aKey[0];
  if( x>=0x09 && x<=0x13 ){
    isNeg = 1;
    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;
    e--;
  }while( aKey[i++] & 1 );
  while( (e--)>0 ){ m = m*100; }

  if( isNeg ){
    *pVal = -m;
  }else{
    *pVal = m;
  }
  return m==0 ? 0 : i;
}
Changes to src/vdbecursor.c.
1
2
3
4
5
6
7
8
9
/*
** 2012-02-16
**
** 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.

|







1
2
3
4
5
6
7
8
9
/*
** 2012 February 16
**
** 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.
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
** first element is sought if iEnd==+1 and the last element if iEnd==-1.
**
** Return SQLITE4_OK on success. Return SQLITE4_NOTFOUND if the table is empty.
*  Other error codes are also possible for various kinds of errors.
*/
int sqlite4VdbeSeekEnd(VdbeCursor *pC, int iEnd){
  KVCursor *pCur = pC->pKVCur;
  int rc;

  KVSize nProbe;

  KVByteArray aProbe[16];

  assert( iEnd==(+1) || iEnd==(-1) || iEnd==(-2) );  
  if( pC->iRoot==KVSTORE_ROOT ){
    if( iEnd>0 ){
      rc = sqlite4KVCursorSeek(pCur, (const KVByteArray *)"\00", 1, iEnd);
    }else{
      nProbe = sqlite4PutVarint64(aProbe, LARGEST_INT64);
      rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe, iEnd);
    }
    if( rc==SQLITE4_INEXACT ) rc = SQLITE4_OK;
  }else{
    const KVByteArray *aKey;
    KVSize nKey;

    nProbe = sqlite4PutVarint64(aProbe, pC->iRoot);
    aProbe[nProbe] = 0xFF;

    rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe+(iEnd<0), iEnd);
    if( rc==SQLITE4_OK ){
      rc = SQLITE4_CORRUPT_BKPT;
    }else if( rc==SQLITE4_INEXACT ){
      rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
      if( rc==SQLITE4_OK && (nKey<nProbe || memcmp(aKey, aProbe, nProbe)!=0) ){
        rc = SQLITE4_NOTFOUND;
      }
    }
    pC->rowChnged = 1;
  }

  return rc;
}

/*
** Move a VDBE cursor to the next element in its table.
** Return SQLITE4_NOTFOUND if the seek falls of the end of the table.
*/
int sqlite4VdbeNext(VdbeCursor *pC){
  KVCursor *pCur = pC->pKVCur;
  const KVByteArray *aKey;
  KVSize nKey;
  int rc;
  sqlite4_uint64 iTabno;

  rc = sqlite4KVCursorNext(pCur);
  if( rc==SQLITE4_OK && pC->iRoot!=KVSTORE_ROOT ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      iTabno = 0;
      sqlite4GetVarint64(aKey, nKey, &iTabno);
      if( iTabno!=pC->iRoot ) rc = SQLITE4_NOTFOUND;
    }
  }
  pC->rowChnged = 1;
  return rc;
}

/*
** Move a VDBE cursor to the previous element in its table.
** Return SQLITE4_NOTFOUND if the seek falls of the end of the table.
*/
int sqlite4VdbePrevious(VdbeCursor *pC){
  KVCursor *pCur = pC->pKVCur;
  const KVByteArray *aKey;
  KVSize nKey;
  int rc;
  sqlite4_uint64 iTabno;

  rc = sqlite4KVCursorPrev(pCur);
  if( rc==SQLITE4_OK && pC->iRoot!=KVSTORE_ROOT ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      iTabno = 0;
      sqlite4GetVarint64(aKey, nKey, &iTabno);
      if( iTabno!=pC->iRoot ) rc = SQLITE4_NOTFOUND;
    }
  }
  pC->rowChnged = 1;
  return rc;
}


/*
** Close a VDBE cursor and release all the resources that cursor 
** happens to hold.
*/
void sqlite4VdbeFreeCursor(VdbeCursor *pCx){
  if( pCx==0 ){
    return;
  }
  sqlite4Fts5Close(pCx->pFts);
  if( pCx->pKVCur ){
    sqlite4KVCursorClose(pCx->pKVCur);
  }
  if( pCx->pTmpKV ){
    sqlite4KVStoreClose(pCx->pTmpKV);
  }
  if( pCx->pDecoder ){
    sqlite4VdbeDecoderDestroy(pCx->pDecoder);
    pCx->pDecoder = 0;
  }
  sqlite4_buffer_clear(&pCx->sSeekKey);
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if( pCx->pVtabCursor ){
    sqlite4_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
    const sqlite4_module *pModule = pCx->pModule;
    p->inVtabMethod = 1;
    pModule->xClose(pVtabCursor);
    p->inVtabMethod = 0;
  }
#endif
}


/*
** Cursor pPk is open on a primary key index. If there is currently a
** deferred seek pending on the cursor, do the actual seek now.
**
** If the operation is a success, SQLITE4_OK is returned. Or, if the
** required entry is not found in the PK index, SQLITE4_CORRUPT. Or if 
** some other error occurs, an error code is returned.
*/
int sqlite4VdbeCursorMoveto(VdbeCursor *pPk){
  int rc = SQLITE4_OK;            /* Return code */
  if( pPk->sSeekKey.n!=0 ){
    assert( pPk->pKeyInfo->nPK==0 );
    rc = sqlite4KVCursorSeek(pPk->pKVCur, pPk->sSeekKey.p, pPk->sSeekKey.n, 0);
    if( rc==SQLITE4_NOTFOUND ){
      rc = SQLITE4_CORRUPT_BKPT;
    }
    pPk->nullRow = 0;
    pPk->sSeekKey.n = 0;
    pPk->rowChnged = 1;
  }
  return rc;
}







|
>

>



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

|
|
|
|
|
|
|
|
<
<

















|







<















|







<


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
























































** first element is sought if iEnd==+1 and the last element if iEnd==-1.
**
** Return SQLITE4_OK on success. Return SQLITE4_NOTFOUND if the table is empty.
*  Other error codes are also possible for various kinds of errors.
*/
int sqlite4VdbeSeekEnd(VdbeCursor *pC, int iEnd){
  KVCursor *pCur = pC->pKVCur;
  const KVByteArray *aKey;
  KVSize nKey;
  KVSize nProbe;
  int rc;
  KVByteArray aProbe[16];

  assert( iEnd==(+1) || iEnd==(-1) || iEnd==(-2) );  












  nProbe = sqlite4PutVarint64(aProbe, pC->iRoot);
  aProbe[nProbe] = 0xFF;

  rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe+(iEnd<0), iEnd);
  if( rc==SQLITE4_OK ){
    rc = SQLITE4_CORRUPT_BKPT;
  }else if( rc==SQLITE4_INEXACT ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE4_OK && (nKey<nProbe || memcmp(aKey, aProbe, nProbe)!=0) ){
      rc = SQLITE4_NOTFOUND;
    }


  }

  return rc;
}

/*
** Move a VDBE cursor to the next element in its table.
** Return SQLITE4_NOTFOUND if the seek falls of the end of the table.
*/
int sqlite4VdbeNext(VdbeCursor *pC){
  KVCursor *pCur = pC->pKVCur;
  const KVByteArray *aKey;
  KVSize nKey;
  int rc;
  sqlite4_uint64 iTabno;

  rc = sqlite4KVCursorNext(pCur);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      iTabno = 0;
      sqlite4GetVarint64(aKey, nKey, &iTabno);
      if( iTabno!=pC->iRoot ) rc = SQLITE4_NOTFOUND;
    }
  }

  return rc;
}

/*
** Move a VDBE cursor to the previous element in its table.
** Return SQLITE4_NOTFOUND if the seek falls of the end of the table.
*/
int sqlite4VdbePrevious(VdbeCursor *pC){
  KVCursor *pCur = pC->pKVCur;
  const KVByteArray *aKey;
  KVSize nKey;
  int rc;
  sqlite4_uint64 iTabno;

  rc = sqlite4KVCursorPrev(pCur);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc==SQLITE4_OK ){
      iTabno = 0;
      sqlite4GetVarint64(aKey, nKey, &iTabno);
      if( iTabno!=pC->iRoot ) rc = SQLITE4_NOTFOUND;
    }
  }

  return rc;
}
























































Changes to src/vdbemem.c.
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
*/
int sqlite4VdbeMemIntegerify(Mem *pMem){
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags & MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

  if( (pMem->flags & MEM_Int)==0 ){
    if( pMem->flags & (MEM_Real|MEM_Null) ){
      pMem->u.num = sqlite4_num_from_int64(sqlite4VdbeIntValue(pMem));
    }else{
      unsigned int flags = pMem->enc |
          SQLITE4_INTEGER_ONLY|SQLITE4_PREFIX_ONLY|SQLITE4_IGNORE_WHITESPACE;
      pMem->u.num = sqlite4_num_from_text(pMem->z, pMem->n, flags, 0);
    }
    MemSetTypeFlag(pMem, MEM_Int);
  }
  return SQLITE4_OK;
}

/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite4VdbeMemNumerify(Mem *pMem){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
    int bReal = 0;
    int flags = (pMem->enc | SQLITE4_PREFIX_ONLY | SQLITE4_IGNORE_WHITESPACE);

    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
    pMem->u.num = sqlite4_num_from_text(pMem->z, pMem->n, flags, 0);
    sqlite4_num_to_int64(pMem->u.num, &bReal);
    MemSetTypeFlag(pMem, (bReal ? MEM_Real : MEM_Int));
  }
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
  pMem->flags &= ~(MEM_Str|MEM_Blob);
  return SQLITE4_OK;
}








<
|
<
<
<
<
<




















|
<







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
*/
int sqlite4VdbeMemIntegerify(Mem *pMem){
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags & MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

  if( (pMem->flags & MEM_Int)==0 ){

    pMem->u.num = sqlite4_num_from_int64(sqlite4VdbeIntValue(pMem));





    MemSetTypeFlag(pMem, MEM_Int);
  }
  return SQLITE4_OK;
}

/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite4VdbeMemNumerify(Mem *pMem){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
    int bReal = 0;
    int flags = (pMem->enc | SQLITE4_PREFIX_ONLY | SQLITE4_IGNORE_WHITESPACE);

    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
    pMem->u.num = sqlite4_num_from_text(pMem->z, pMem->n, flags, &bReal);

    MemSetTypeFlag(pMem, (bReal ? MEM_Real : MEM_Int));
  }
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
  pMem->flags &= ~(MEM_Str|MEM_Blob);
  return SQLITE4_OK;
}

Changes to src/where.c.
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
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
*/
#include "sqliteInt.h"

/* For VdbeCodecEncodeKey() - revisit this */
#include "vdbeInt.h"


/*
** Trace output macros
*/
#if defined(SQLITE4_TEST) || defined(SQLITE4_DEBUG)
/***/ int sqlite4WhereTrace = 0;
#endif
#if defined(SQLITE4_DEBUG) \
    && (defined(SQLITE4_TEST) || defined(SQLITE4_ENABLE_WHERETRACE))
# define WHERETRACE(K,X)  if(sqlite4WhereTrace&(K)) sqlite4DebugPrintf X
# define WHERETRACE_ENABLED 1
#else
# define WHERETRACE(K,X)
#endif

/* Forward reference
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
typedef struct WhereLevel WhereLevel;
typedef struct WhereLoop WhereLoop;
typedef struct WherePath WherePath;
typedef struct WhereTerm WhereTerm;
typedef struct WhereLoopBuilder WhereLoopBuilder;
typedef struct WhereScan WhereScan;
typedef struct WhereOrCost WhereOrCost;
typedef struct WhereOrSet WhereOrSet;

/*
** Cost X is tracked as 10*log2(X) stored in a 16-bit integer.  The
** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
** (Virtual tables can return a larger cost, but let's assume they do not.)
** So all costs can be stored in a 16-bit unsigned integer without risk
** of overflow.
**
** Costs are estimates, so don't go to the computational trouble to compute
** 10*log2(X) exactly.  Instead, a close estimate is used.  Any value of
** X<=1 is stored as 0.  X=2 is 10.  X=3 is 16.  X=1000 is 99. etc.
**
** The tool/wherecosttest.c source file implements a command-line program
** that will convert between WhereCost to integers and do addition and
** multiplication on WhereCost values.  That command-line program is a
** useful utility to have around when working with this module.
*/
typedef unsigned short int WhereCost;

/*
** This object contains information needed to implement a single nested
** loop in WHERE clause.
**
** Contrast this object with WhereLoop.  This object describes the
** implementation of the loop.  WhereLoop describes the algorithm.
** This object contains a pointer to the WhereLoop algorithm as one of
** its elements.
**
** The WhereInfo object contains a single instance of this object for
** each term in the FROM clause (which is to say, for each of the
** nested loops as implemented).  The order of WhereLevel objects determines
** the loop nested order, with WhereInfo.a[0] being the outer loop and
** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
*/
struct WhereLevel {
  int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
  int iTabCur;          /* The VDBE cursor used to access the table */
  int iIdxCur;          /* The VDBE cursor used to access pIdx */
  int addrBrk;          /* Jump here to break out of the loop */
  int addrNxt;          /* Jump here to start the next IN combination */
  int addrCont;         /* Jump here to continue with the next loop cycle */
  int addrFirst;        /* First instruction of interior of the loop */
  u8 iFrom;             /* Which entry in the FROM clause */
  u8 op, p5;            /* Opcode and P5 of the opcode that ends the loop */
  int p1, p2;           /* Operands of the opcode used to ends the loop */
  union {               /* Information that depends on pWLoop->wsFlags */
    struct {
      int nIn;              /* Number of entries in aInLoop[] */
      struct InLoop {
        int iCur;              /* The VDBE cursor used by this IN operator */
        int addrInTop;         /* Top of the IN loop */
        u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
      } *aInLoop;           /* Information about each nested IN operator */
    } in;                 /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
  } u;
  struct WhereLoop *pWLoop;  /* The selected WhereLoop object */
};

/*
** Each instance of this object represents an algorithm for evaluating one
** term of a join.  Every term of the FROM clause will have at least
** one corresponding WhereLoop object (unless INDEXED BY constraints
** prevent a query solution - which is an error) and many terms of the
** FROM clause will have multiple WhereLoop objects, each describing a
** potential way of implementing that FROM-clause term, together with
** dependencies and cost estimates for using the chosen algorithm.
**
** Query planning consists of building up a collection of these WhereLoop
** objects, then computing a particular sequence of WhereLoop objects, with
** one WhereLoop object per FROM clause term, that satisfy all dependencies
** and that minimize the overall cost.
*/
struct WhereLoop {
  Bitmask prereq;       /* Bitmask of other loops that must run first */
  Bitmask maskSelf;     /* Bitmask identifying table iTab */
#ifdef SQLITE4_DEBUG
  char cId;             /* Symbolic ID of this loop for debugging use */
#endif
  u8 iTab;              /* Position in FROM clause of table for this loop */
  u8 iSortIdx;          /* Sorting index number.  0==None */
  WhereCost rSetup;     /* One-time setup cost (ex: create transient index) */
  WhereCost rRun;       /* Cost of running each loop */
  WhereCost nOut;       /* Estimated number of output rows */
  union {
    struct {               /* Information for internal btree tables */
      int nEq;               /* Number of equality constraints */
      Index *pIndex;         /* Index used, or NULL */
    } btree;
    struct {               /* Information for virtual tables */
      int idxNum;            /* Index number */
      u8 needFree;           /* True if sqlite4_free(idxStr) is needed */
      u8 isOrdered;          /* True if satisfies ORDER BY */
      u16 omitMask;          /* Terms that may be omitted */
      char *idxStr;          /* Index identifier string */
    } vtab;
  } u;
  u32 wsFlags;          /* WHERE_* flags describing the plan */
  u16 nLTerm;           /* Number of entries in aLTerm[] */
  /**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
  u16 nLSlot;           /* Number of slots allocated for aLTerm[] */
  WhereTerm **aLTerm;   /* WhereTerms used */
  WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
  WhereTerm *aLTermSpace[4];  /* Initial aLTerm[] space */
};

/* This object holds the prerequisites and the cost of running a
** subquery on one operand of an OR operator in the WHERE clause.
** See WhereOrSet for additional information 
*/
struct WhereOrCost {
  Bitmask prereq;     /* Prerequisites */
  WhereCost rRun;     /* Cost of running this subquery */
  WhereCost nOut;     /* Number of outputs for this subquery */
};

/* The WhereOrSet object holds a set of possible WhereOrCosts that
** correspond to the subquery(s) of OR-clause processing.  At most
** favorable N_OR_COST elements are retained.
*/
#define N_OR_COST 3
struct WhereOrSet {
  u16 n;                      /* Number of valid a[] entries */
  WhereOrCost a[N_OR_COST];   /* Set of best costs */
};


/* Forward declaration of methods */
static int whereLoopResize(sqlite4*, WhereLoop*, int);

/*
** Each instance of this object holds a sequence of WhereLoop objects
** that implement some or all of a query plan.
**
** Think of each WhereLoop object as a node in a graph with arcs
** showing dependences and costs for travelling between nodes.  (That is
** not a completely accurate description because WhereLoop costs are a
** vector, not a scalar, and because dependences are many-to-one, not
** one-to-one as are graph nodes.  But it is a useful visualization aid.)
** Then a WherePath object is a path through the graph that visits some
** or all of the WhereLoop objects once.
**
** The "solver" works by creating the N best WherePath objects of length
** 1.  Then using those as a basis to compute the N best WherePath objects
** of length 2.  And so forth until the length of WherePaths equals the
** number of nodes in the FROM clause.  The best (lowest cost) WherePath
** at the end is the choosen query plan.
*/
struct WherePath {
  Bitmask maskLoop;     /* Bitmask of all WhereLoop objects in this path */
  Bitmask revLoop;      /* aLoop[]s that should be reversed for ORDER BY */
  WhereCost nRow;       /* Estimated number of rows generated by this path */
  WhereCost rCost;      /* Total cost of this path */
  u8 isOrdered;         /* True if this path satisfies ORDER BY */
  u8 isOrderedValid;    /* True if the isOrdered field is valid */
  WhereLoop **aLoop;    /* Array of WhereLoop objects implementing this path */
};

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by AND operators,
** usually, or sometimes subexpressions separated by OR.
**







>





|

|
<
<
|

|








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







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
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
*/
#include "sqliteInt.h"

/* For VdbeCodecEncodeKey() - revisit this */
#include "vdbeInt.h"


/*
** Trace output macros
*/
#if defined(SQLITE4_TEST) || defined(SQLITE4_DEBUG)
int sqlite4WhereTrace = 0;
#endif
#if defined(SQLITE4_TEST) && defined(SQLITE4_DEBUG)


# define WHERETRACE(X)  if(sqlite4WhereTrace) sqlite4DebugPrintf X
#else
# define WHERETRACE(X)
#endif

/* Forward reference
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;

typedef struct WhereCost WhereCost;





































































































































































/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by AND operators,
** usually, or sometimes subexpressions separated by OR.
**
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
** bits in the Bitmask.  So, in the example above, the cursor numbers
** would be mapped into integers 0 through 7.
**
** The number of terms in a join is limited by the number of bits
** in prereqRight and prereqAll.  The default is 64 bits, hence SQLite
** is only able to process joins with 64 or fewer tables.
*/

struct WhereTerm {
  Expr *pExpr;            /* Pointer to the subexpression that is this term */
  int iParent;            /* Disable pWC->a[iParent] when this term disabled */
  int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
  union {
    int leftColumn;         /* Column number of X in "X <op> <expr>" */
    WhereOrInfo *pOrInfo;   /* Extra information if (eOperator & WO_OR)!=0 */
    WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
  } u;
  u16 eOperator;          /* A WO_xx value describing <op> */
  u8 wtFlags;             /* TERM_xxx bit flags.  See below */
  u8 nChild;              /* Number of children that must disable us */
  WhereClause *pWC;       /* The clause this term is part of */
  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */







>






|
|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
** bits in the Bitmask.  So, in the example above, the cursor numbers
** would be mapped into integers 0 through 7.
**
** The number of terms in a join is limited by the number of bits
** in prereqRight and prereqAll.  The default is 64 bits, hence SQLite
** is only able to process joins with 64 or fewer tables.
*/
typedef struct WhereTerm WhereTerm;
struct WhereTerm {
  Expr *pExpr;            /* Pointer to the subexpression that is this term */
  int iParent;            /* Disable pWC->a[iParent] when this term disabled */
  int leftCursor;         /* Cursor number of X in "X <op> <expr>" */
  union {
    int leftColumn;         /* Column number of X in "X <op> <expr>" */
    WhereOrInfo *pOrInfo;   /* Extra information if eOperator==WO_OR */
    WhereAndInfo *pAndInfo; /* Extra information if eOperator==WO_AND */
  } u;
  u16 eOperator;          /* A WO_xx value describing <op> */
  u8 wtFlags;             /* TERM_xxx bit flags.  See below */
  u8 nChild;              /* Number of children that must disable us */
  WhereClause *pWC;       /* The clause this term is part of */
  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
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
#define TERM_OR_OK      0x40   /* Used during OR-clause processing */
#ifdef SQLITE4_ENABLE_STAT3
#  define TERM_VNULL    0x80   /* Manufactured x>NULL or x<=NULL term */
#else
#  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
#endif

/*
** An instance of the WhereScan object is used as an iterator for locating
** terms in the WHERE clause that are useful to the query planner.
*/
struct WhereScan {
  WhereClause *pOrigWC;      /* Original, innermost WhereClause */
  WhereClause *pWC;          /* WhereClause currently being scanned */
  char *zCollName;           /* Required collating sequence, if not NULL */
  char idxaff;               /* Must match this affinity, if zCollName!=NULL */
  unsigned char nEquiv;      /* Number of entries in aEquiv[] */
  unsigned char iEquiv;      /* Next unused slot in aEquiv[] */
  u32 opMask;                /* Acceptable operators */
  int k;                     /* Resume scanning at this->pWC->a[this->k] */
  int aEquiv[22];            /* Cursor,Column pairs for equivalence classes */
};

/*
** An instance of the following structure holds all information about a
** WHERE clause.  Mostly this is a container for one or more WhereTerms.
**
** Explanation of pOuter:  For a WHERE clause of the form
**
**           a AND ((b AND c) OR (d AND e)) AND f
**
** There are separate WhereClause objects for the whole clause and for
** the subclauses "(b AND c)" and "(d AND e)".  The pOuter field of the
** subclauses points to the WhereClause object for the whole clause.
*/
struct WhereClause {
  WhereInfo *pWInfo;       /* WHERE clause processing context */


  WhereClause *pOuter;     /* Outer conjunction */
  u8 op;                   /* Split operator.  TK_AND or TK_OR */

  int nTerm;               /* Number of terms */
  int nSlot;               /* Number of entries in a[] */
  WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
#if defined(SQLITE4_SMALL_STACK)
  WhereTerm aStatic[1];    /* Initial static space for a[] */
#else
  WhereTerm aStatic[8];    /* Initial static space for a[] */







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













|
>
>


>







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
#define TERM_OR_OK      0x40   /* Used during OR-clause processing */
#ifdef SQLITE4_ENABLE_STAT3
#  define TERM_VNULL    0x80   /* Manufactured x>NULL or x<=NULL term */
#else
#  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
#endif

















/*
** An instance of the following structure holds all information about a
** WHERE clause.  Mostly this is a container for one or more WhereTerms.
**
** Explanation of pOuter:  For a WHERE clause of the form
**
**           a AND ((b AND c) OR (d AND e)) AND f
**
** There are separate WhereClause objects for the whole clause and for
** the subclauses "(b AND c)" and "(d AND e)".  The pOuter field of the
** subclauses points to the WhereClause object for the whole clause.
*/
struct WhereClause {
  Parse *pParse;           /* The parser context */
  WhereMaskSet *pMaskSet;  /* Mapping of table cursor numbers to bitmasks */
  Bitmask vmask;           /* Bitmask identifying virtual table cursors */
  WhereClause *pOuter;     /* Outer conjunction */
  u8 op;                   /* Split operator.  TK_AND or TK_OR */
  u16 wctrlFlags;          /* Might include WHERE_AND_ONLY */
  int nTerm;               /* Number of terms */
  int nSlot;               /* Number of entries in a[] */
  WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
#if defined(SQLITE4_SMALL_STACK)
  WhereTerm aStatic[1];    /* Initial static space for a[] */
#else
  WhereTerm aStatic[8];    /* Initial static space for a[] */
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
};

/*
** An instance of the following structure keeps track of a mapping
** between VDBE cursor numbers and bits of the bitmasks in WhereTerm.
**
** The VDBE cursor numbers are small integers contained in 
** SrcListItem.iCursor and Expr.iTable fields.  For any given WHERE 
** clause, the cursor numbers might not begin with 0 and they might
** contain gaps in the numbering sequence.  But we want to make maximum
** use of the bits in our bitmasks.  This structure provides a mapping
** from the sparse cursor numbers into consecutive integers beginning
** with 0.
**
** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
};

/*
** An instance of the following structure keeps track of a mapping
** between VDBE cursor numbers and bits of the bitmasks in WhereTerm.
**
** The VDBE cursor numbers are small integers contained in 
** SrcList_item.iCursor and Expr.iTable fields.  For any given WHERE 
** clause, the cursor numbers might not begin with 0 and they might
** contain gaps in the numbering sequence.  But we want to make maximum
** use of the bits in our bitmasks.  This structure provides a mapping
** from the sparse cursor numbers into consecutive integers beginning
** with 0.
**
** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
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
*/
struct WhereMaskSet {
  int n;                        /* Number of assigned cursor values */
  int ix[BMS];                  /* Cursor assigned to each bit */
};

/*
** This object is a convenience wrapper holding all information needed
** to construct WhereLoop objects for a particular query.
*/
struct WhereLoopBuilder {
  WhereInfo *pWInfo;        /* Information about this WHERE */
  WhereClause *pWC;         /* WHERE clause terms */
  ExprList *pOrderBy;       /* ORDER BY clause */
  WhereLoop *pNew;          /* Template WhereLoop */
  WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
**
** An instance of this object holds the complete state of the query
** planner.
*/
struct WhereInfo {
  Parse *pParse;            /* Parsing and code generating context */
  SrcList *pTabList;        /* List of tables in the join */
  ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
  ExprList *pResultSet;     /* Result set. DISTINCT operates on these */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  WhereCost nRowOut;        /* Estimated number of output rows */
  u16 wctrlFlags;           /* Flags originally passed to sqlite4WhereBegin() */
  u8 bOBSat;                /* ORDER BY satisfied by indices */
  u8 okOnePass;             /* Ok to use one-pass algorithm for UPDATE/DELETE */
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values below */
  u8 nLevel;                /* Number of nested loop */
  int iTop;                 /* The very beginning of the WHERE loop */
  int iContinue;            /* Jump here to continue with next record */
  int iBreak;               /* Jump here to break out of the loop */
  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
  WhereClause sWC;          /* Decomposition of the WHERE clause */
  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/*
** Bitmasks for the operators on WhereTerm objects.  These are all
** operators that are of interest to the query planner.  An
** OR-ed combination of these values can be used when searching for
** particular WhereTerms within a WhereClause.
*/
#define WO_IN     0x001
#define WO_EQ     0x002
#define WO_LT     (WO_EQ<<(TK_LT-TK_EQ))
#define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
#define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
#define WO_MATCH  0x040
#define WO_ISNULL 0x080
#define WO_OR     0x100       /* Two or more OR-connected terms */
#define WO_AND    0x200       /* Two or more AND-connected terms */
#define WO_EQUIV  0x400       /* Of the form A==B, both columns */
#define WO_NOOP   0x800       /* This term does not restrict search space */

#define WO_ALL    0xfff       /* Mask of all possible WO_* values */
#define WO_SINGLE 0x0ff       /* Mask of all non-compound WO_* values */

/*
** These are definitions of bits in the WhereLoop.wsFlags field.
** The particular combination of bits in each WhereLoop help to
** determine the algorithm that WhereLoop represents.
*/
#define WHERE_COLUMN_EQ    0x00000001  /* x=EXPR */
#define WHERE_COLUMN_RANGE 0x00000002  /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN    0x00000004  /* x IN (...) */
#define WHERE_COLUMN_NULL  0x00000008  /* x IS NULL */
#define WHERE_CONSTRAINT   0x0000000f  /* Any of the WHERE_COLUMN_xxx values */
#define WHERE_TOP_LIMIT    0x00000010  /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT    0x00000020  /* x>EXPR or x>=EXPR constraint */
#define WHERE_BOTH_LIMIT   0x00000030  /* Both x>EXPR and x<EXPR */
#define WHERE_IDX_ONLY     0x00000040  /* Use index only - omit table */
#define WHERE_PRIMARY_KEY  0x00000100  /* Index is the PK index */
#define WHERE_INDEXED      0x00000200  /* WhereLoop.u.btree.pIndex is valid */
#define WHERE_VIRTUALTABLE 0x00000400  /* WhereLoop.u.vtab is valid */
#define WHERE_IN_ABLE      0x00000800  /* Able to support an IN operator */
#define WHERE_ONEROW       0x00001000  /* Selects no more than one row */
#define WHERE_MULTI_OR     0x00002000  /* OR using multiple indices */
#define WHERE_AUTO_INDEX   0x00004000  /* Uses an ephemeral index */


/* Convert a WhereCost value (10 times log2(X)) into its integer value X.
** A rough approximation is used.  The value returned is not exact.
*/
static u64 whereCostToInt(WhereCost x){
  u64 n;
  if( x<10 ) return 1;
  n = x%10;
  x /= 10;
  if( n>=5 ) n -= 2;
  else if( n>=1 ) n -= 1;
  if( x>=3 ) return (n+8)<<(x-3);
  return (n+8)>>(3-x);
}

/*
** Return the estimated number of output rows from a WHERE clause
*/
u64 sqlite4WhereOutputRowCount(WhereInfo *pWInfo){
  return whereCostToInt(pWInfo->nRowOut);
}

/*
** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
** WHERE clause returns outputs for DISTINCT processing.
*/
int sqlite4WhereIsDistinct(WhereInfo *pWInfo){
  return pWInfo->eDistinct;
}

/*
** Return TRUE if the WHERE clause returns rows in ORDER BY order.
** Return FALSE if the output needs to be sorted.
*/
int sqlite4WhereIsOrdered(WhereInfo *pWInfo){
  return pWInfo->bOBSat!=0;
}

/*
** Return the VDBE address or label to jump to in order to continue

** immediately with the next row of a WHERE clause.
*/
int sqlite4WhereContinueLabel(WhereInfo *pWInfo){
  return pWInfo->iContinue;
}


/*
** Return the VDBE address or label to jump to in order to break
** out of a WHERE loop.
*/
int sqlite4WhereBreakLabel(WhereInfo *pWInfo){
  return pWInfo->iBreak;
}


/*
** Return TRUE if an UPDATE or DELETE statement can operate directly on
** the rowids returned by a WHERE clause.  Return FALSE if doing an
** UPDATE or DELETE might change subsequent WHERE clause results.
*/
int sqlite4WhereOkOnePass(WhereInfo *pWInfo){
  return pWInfo->okOnePass;
}

/*
** Move the content of pSrc into pDest
*/
static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
  pDest->n = pSrc->n;
  memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
}

/*
** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
**
** The new entry might overwrite an existing entry, or it might be
** appended, or it might be discarded.  Do whatever is the right thing
** so that pSet keeps the N_OR_COST best entries seen so far.
*/
static int whereOrInsert(
  WhereOrSet *pSet,      /* The WhereOrSet to be updated */
  Bitmask prereq,        /* Prerequisites of the new entry */
  WhereCost rRun,        /* Run-cost of the new entry */
  WhereCost nOut         /* Number of outputs for the new entry */
){
  u16 i;
  WhereOrCost *p;
  for(i=pSet->n, p=pSet->a; i>0; i--, p++){
    if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
      goto whereOrInsert_done;
    }
    if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
      return 0;
    }
  }
  if( pSet->n<N_OR_COST ){
    p = &pSet->a[pSet->n++];
    p->nOut = nOut;
  }else{
    p = pSet->a;
    for(i=1; i<pSet->n; i++){
      if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
    }
    if( p->rRun<=rRun ) return 0;
  }
whereOrInsert_done:
  p->prereq = prereq;
  p->rRun = rRun;
  if( p->nOut>nOut ) p->nOut = nOut;
  return 1;
}

/*
** Initialize a preallocated WhereClause structure.
*/
static void whereClauseInit(
  WhereClause *pWC,        /* The WhereClause to be initialized */
  WhereInfo *pWInfo        /* The WHERE processing context */


){
  pWC->pWInfo = pWInfo;

  pWC->pOuter = 0;
  pWC->nTerm = 0;
  pWC->nSlot = ArraySize(pWC->aStatic);
  pWC->a = pWC->aStatic;


}

/* Forward reference */
static void whereClauseClear(WhereClause*);

/*
** Deallocate all memory associated with a WhereOrInfo object.







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

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



|
<

|











<






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

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






|
>
>

|
>




>
>







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
*/
struct WhereMaskSet {
  int n;                        /* Number of assigned cursor values */
  int ix[BMS];                  /* Cursor assigned to each bit */
};

/*










** A WhereCost object records a lookup strategy and the estimated








** cost of pursuing that strategy.
*/
struct WhereCost {


  WherePlan plan;    /* The lookup strategy */



  double rCost;      /* Overall cost of pursuing this search strategy */









  Bitmask used;      /* Bitmask of cursors used by this plan */



};

/*
** Bitmasks for the operators that indices are able to exploit.  An

** OR-ed combination of these values can be used when searching for
** terms in the where clause.
*/
#define WO_IN     0x001
#define WO_EQ     0x002
#define WO_LT     (WO_EQ<<(TK_LT-TK_EQ))
#define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
#define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
#define WO_MATCH  0x040
#define WO_ISNULL 0x080
#define WO_OR     0x100       /* Two or more OR-connected terms */
#define WO_AND    0x200       /* Two or more AND-connected terms */

#define WO_NOOP   0x800       /* This term does not restrict search space */

#define WO_ALL    0xfff       /* Mask of all possible WO_* values */
#define WO_SINGLE 0x0ff       /* Mask of all non-compound WO_* values */

/*
** Value for wsFlags returned by bestIndex() and stored in
** WhereLevel.wsFlags.  These flags determine which search
** strategies are appropriate.
**
** The least significant 12 bits is reserved as a mask for WO_ values above.















** 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 */
#define WHERE_TOP_LIMIT    0x00100000  /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT    0x00200000  /* x>EXPR or x>=EXPR constraint */
#define WHERE_BOTH_LIMIT   0x00300000  /* Both x>EXPR and x<EXPR */
#define WHERE_IDX_ONLY     0x00800000  /* Use index only - omit table */

#define WHERE_ORDERBY      0x01000000  /* Output will appear in correct order */
#define WHERE_REVERSE      0x02000000  /* Scan in reverse order */
#define WHERE_UNIQUE       0x04000000  /* Selects no more than one row */
#define WHERE_VIRTUALTABLE 0x08000000  /* Use virtual-table processing */
#define WHERE_MULTI_OR     0x10000000  /* OR using multiple indices */





#define WHERE_TEMP_INDEX   0x20000000  /* Uses an ephemeral index */







#define WHERE_DISTINCT     0x40000000  /* Correct order for DISTINCT */








































/*
** Initialize a preallocated WhereClause structure.
*/
static void whereClauseInit(
  WhereClause *pWC,        /* The WhereClause to be initialized */
  Parse *pParse,           /* The parsing context */
  WhereMaskSet *pMaskSet,  /* Mapping from table cursor numbers to bitmasks */
  u16 wctrlFlags           /* Might include WHERE_AND_ONLY */
){
  pWC->pParse = pParse;
  pWC->pMaskSet = pMaskSet;
  pWC->pOuter = 0;
  pWC->nTerm = 0;
  pWC->nSlot = ArraySize(pWC->aStatic);
  pWC->a = pWC->aStatic;
  pWC->vmask = 0;
  pWC->wctrlFlags = wctrlFlags;
}

/* Forward reference */
static void whereClauseClear(WhereClause*);

/*
** Deallocate all memory associated with a WhereOrInfo object.
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
/*
** Deallocate a WhereClause structure.  The WhereClause structure
** itself is not freed.  This routine is the inverse of whereClauseInit().
*/
static void whereClauseClear(WhereClause *pWC){
  int i;
  WhereTerm *a;
  sqlite4 *db = pWC->pWInfo->pParse->db;
  for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
    if( a->wtFlags & TERM_DYNAMIC ){
      sqlite4ExprDelete(db, a->pExpr);
    }
    if( a->wtFlags & TERM_ORINFO ){
      whereOrInfoDelete(db, a->u.pOrInfo);
    }else if( a->wtFlags & TERM_ANDINFO ){
      whereAndInfoDelete(db, a->u.pAndInfo);
    }
  }
  if( pWC->a!=pWC->aStatic ){
    sqlite4DbFree(db, pWC->a);
  }
}


/*
** Skip over any TK_COLLATE and/or TK_AS operators at the root of
** an expression.
**
** NOTE: This function was added when the NGQP was imported from SQLite3.
** At present it is not actually possible for Expr.op to be set to 
** TK_COLLATE. But will be if the way Expr objects represent collation
** sequences is changed to match SQLite3.
*/
static Expr *sqlite4ExprSkipCollate(Expr *pExpr){
  assert( pExpr==0 || pExpr->op!=TK_COLLATE );

  while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
    pExpr = pExpr->pLeft;
  }
  return pExpr;
}

/*
** A bit in a Bitmask
*/
#define MASKBIT(n)   (((Bitmask)1)<<(n))



/*
** Add a single new WhereTerm entry to the WhereClause object pWC.
** The new WhereTerm object is constructed from Expr p and with wtFlags.
** The index in pWC->a[] of the new WhereTerm is returned on success.
** 0 is returned if the new WhereTerm could not be added due to a memory
** allocation error.  The memory allocation failure will be recorded in







|














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







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
/*
** Deallocate a WhereClause structure.  The WhereClause structure
** itself is not freed.  This routine is the inverse of whereClauseInit().
*/
static void whereClauseClear(WhereClause *pWC){
  int i;
  WhereTerm *a;
  sqlite4 *db = pWC->pParse->db;
  for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
    if( a->wtFlags & TERM_DYNAMIC ){
      sqlite4ExprDelete(db, a->pExpr);
    }
    if( a->wtFlags & TERM_ORINFO ){
      whereOrInfoDelete(db, a->u.pOrInfo);
    }else if( a->wtFlags & TERM_ANDINFO ){
      whereAndInfoDelete(db, a->u.pAndInfo);
    }
  }
  if( pWC->a!=pWC->aStatic ){
    sqlite4DbFree(db, pWC->a);
  }
}



























/*
** Add a single new WhereTerm entry to the WhereClause object pWC.
** The new WhereTerm object is constructed from Expr p and with wtFlags.
** The index in pWC->a[] of the new WhereTerm is returned on success.
** 0 is returned if the new WhereTerm could not be added due to a memory
** allocation error.  The memory allocation failure will be recorded in
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
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
  WhereTerm *pTerm;
  int idx;
  testcase( wtFlags & TERM_VIRTUAL );  /* EV: R-00211-15100 */
  if( pWC->nTerm>=pWC->nSlot ){
    WhereTerm *pOld = pWC->a;
    sqlite4 *db = pWC->pWInfo->pParse->db;
    pWC->a = sqlite4DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
    if( pWC->a==0 ){
      if( wtFlags & TERM_DYNAMIC ){
        sqlite4ExprDelete(db, p);
      }
      pWC->a = pOld;
      return 0;
    }
    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
    if( pOld!=pWC->aStatic ){
      sqlite4DbFree(db, pOld);
    }
    pWC->nSlot = sqlite4DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  pTerm->pExpr = sqlite4ExprSkipCollate(p);
  pTerm->wtFlags = wtFlags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;
  return idx;
}

/*







|















|







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
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
  WhereTerm *pTerm;
  int idx;
  testcase( wtFlags & TERM_VIRTUAL );  /* EV: R-00211-15100 */
  if( pWC->nTerm>=pWC->nSlot ){
    WhereTerm *pOld = pWC->a;
    sqlite4 *db = pWC->pParse->db;
    pWC->a = sqlite4DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
    if( pWC->a==0 ){
      if( wtFlags & TERM_DYNAMIC ){
        sqlite4ExprDelete(db, p);
      }
      pWC->a = pOld;
      return 0;
    }
    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
    if( pOld!=pWC->aStatic ){
      sqlite4DbFree(db, pOld);
    }
    pWC->nSlot = sqlite4DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  pTerm->pExpr = p;
  pTerm->wtFlags = wtFlags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;
  return idx;
}

/*
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
** The original WHERE clause in pExpr is unaltered.  All this routine
** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array.  The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
  pWC->op = op;
  if( pExpr==0 ) return;
  if( pExpr->op!=op ){
    whereClauseInsert(pWC, pExpr, 0);
  }else{
    whereSplit(pWC, pExpr->pLeft, op);
    whereSplit(pWC, pExpr->pRight, op);
  }
}

/*
** Initialize a WhereMaskSet object
*/
#define initMaskSet(P)  (P)->n=0

/*
** Return the bitmask for the given cursor number.  Return 0 if
** iCursor is not in the set.
*/
static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
  int i;
  assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
  for(i=0; i<pMaskSet->n; i++){
    if( pMaskSet->ix[i]==iCursor ){
      return MASKBIT(i);
    }
  }
  return 0;
}

/*
** Create a new mask for cursor iCursor.
**
** There is one cursor per table in the FROM clause.  The number of
** tables in the FROM clause is limited by a test early in the
** sqlite4WhereBegin() routine.  So we know that the pMaskSet->ix[]
** array will never overflow.
*/
static void createMask(WhereMaskSet *pMaskSet, int iCursor){
  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
  pMaskSet->ix[pMaskSet->n++] = iCursor;
}

/*
** These routine walk (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.









*/
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){







|
|










|

|










|



















|


>
>
>
>
>
>
>
>
>







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
** The original WHERE clause in pExpr is unaltered.  All this routine
** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array.  The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
  pWC->op = (u8)op;
  if( pExpr==0 ) return;
  if( pExpr->op!=op ){
    whereClauseInsert(pWC, pExpr, 0);
  }else{
    whereSplit(pWC, pExpr->pLeft, op);
    whereSplit(pWC, pExpr->pRight, op);
  }
}

/*
** Initialize an expression mask set (a WhereMaskSet object)
*/
#define initMaskSet(P)  memset(P, 0, sizeof(*P))

/*
** Return the bitmask for the given cursor number.  Return 0 if
** iCursor is not in the set.
*/
static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
  int i;
  assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
  for(i=0; i<pMaskSet->n; i++){
    if( pMaskSet->ix[i]==iCursor ){
      return ((Bitmask)1)<<i;
    }
  }
  return 0;
}

/*
** Create a new mask for cursor iCursor.
**
** There is one cursor per table in the FROM clause.  The number of
** tables in the FROM clause is limited by a test early in the
** sqlite4WhereBegin() routine.  So we know that the pMaskSet->ix[]
** array will never overflow.
*/
static void createMask(WhereMaskSet *pMaskSet, int iCursor){
  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
  pMaskSet->ix[pMaskSet->n++] = iCursor;
}

/*
** This routine walks (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.
**
** In order for this routine to work, the calling function must have
** previously invoked sqlite4ResolveExprNames() on the expression.  See
** the header comment on that routine for additional information.
** The sqlite4ResolveExprNames() routines looks for column names and
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
** the VDBE cursor number of the table.  This routine just has to
** translate the cursor numbers into bitmask values and OR all
** the bitmasks together.
*/
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
  }
  return mask;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
**
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
** of one of the following forms: column = expression column > expression
** column >= expression column < expression column <= expression
** expression = column expression > column expression >= column
** expression < column expression <= column column IN
** (expression-list) column IN (subquery) column IS NULL







|







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
  }
  return mask;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", and "IN".
**
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
** of one of the following forms: column = expression column > expression
** column >= expression column < expression column <= expression
** expression = column expression > column expression >= column
** expression < column expression <= column column IN
** (expression-list) column IN (subquery) column IS NULL
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
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparison operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If left/right precedence rules come into play when determining the
** collating sequence, then COLLATE operators are adjusted to ensure
** that the collating sequence does not change.  For example:
** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on
** the left hand side of a comparison overrides any collation sequence 
** attached to the right. For the same reason the EP_ExpCollate flag
** is not commuted.
*/
static void exprCommute(Parse *pParse, Expr *pExpr){
  u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
  u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
  if( expRight==expLeft ){
    /* Either X and Y both have COLLATE operator or neither do */
    if( expRight ){
      /* Both X and Y have COLLATE operators.  Make sure X is always
      ** used by clearing the EP_ExpCollate flag from Y. */
      pExpr->pRight->flags &= ~EP_ExpCollate;
    }else if( sqlite4ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
      /* Neither X nor Y have COLLATE operators, but X has a non-default

      ** collating sequence.  So add the EP_ExpCollate marker on X to cause
      ** it to be searched first. */
      pExpr->pLeft->flags |= EP_ExpCollate;
    }
  }
  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );







|
|
|
|








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







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
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparison operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If a collation sequence is associated with either the left or right
** side of the comparison, it remains associated with the same side after
** the commutation. So "Y collate NOCASE op X" becomes 
** "X collate NOCASE op Y". This is because any collation sequence on
** the left hand side of a comparison overrides any collation sequence 
** attached to the right. For the same reason the EP_ExpCollate flag
** is not commuted.
*/
static void exprCommute(Parse *pParse, Expr *pExpr){
  u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
  u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );





  pExpr->pRight->pColl = sqlite4ExprCollSeq(pParse, pExpr->pRight);
  pExpr->pLeft->pColl = sqlite4ExprCollSeq(pParse, pExpr->pLeft);

  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
  pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;

  pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;


  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
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
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
1162
1163
  assert( op!=TK_LT || c==WO_LT );
  assert( op!=TK_LE || c==WO_LE );
  assert( op!=TK_GT || c==WO_GT );
  assert( op!=TK_GE || c==WO_GE );
  return c;
}

/*
** Advance to the next WhereTerm that matches according to the criteria
** established when the pScan object was initialized by whereScanInit().
** Return NULL if there are no more matching WhereTerms.
*/
static WhereTerm *whereScanNext(WhereScan *pScan){
  int iCur;            /* The cursor on the LHS of the term */
  int iColumn;         /* The column on the LHS of the term.  -1 for IPK */
  Expr *pX;            /* An expression being tested */
  WhereClause *pWC;    /* Shorthand for pScan->pWC */
  WhereTerm *pTerm;    /* The term being tested */
  int k = pScan->k;    /* Where to start scanning */

  while( pScan->iEquiv<=pScan->nEquiv ){
    iCur = pScan->aEquiv[pScan->iEquiv-2];
    iColumn = pScan->aEquiv[pScan->iEquiv-1];
    while( (pWC = pScan->pWC)!=0 ){
      for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
        if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn ){
          if( (pTerm->eOperator & WO_EQUIV)!=0
           && pScan->nEquiv<ArraySize(pScan->aEquiv)
          ){
            int j;
            pX = sqlite4ExprSkipCollate(pTerm->pExpr->pRight);
            assert( pX->op==TK_COLUMN );
            for(j=0; j<pScan->nEquiv; j+=2){
              if( pScan->aEquiv[j]==pX->iTable
               && pScan->aEquiv[j+1]==pX->iColumn ){
                  break;
              }
            }
            if( j==pScan->nEquiv ){
              pScan->aEquiv[j] = pX->iTable;
              pScan->aEquiv[j+1] = pX->iColumn;
              pScan->nEquiv += 2;
            }
          }
          if( (pTerm->eOperator & pScan->opMask)!=0 ){
            /* Verify the affinity and collating sequence match */
            if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
              CollSeq *pColl;
              Parse *pParse = pWC->pWInfo->pParse;
              pX = pTerm->pExpr;
              if( !sqlite4IndexAffinityOk(pX, pScan->idxaff) ){
                continue;
              }
              assert(pX->pLeft);
              pColl = sqlite4BinaryCompareCollSeq(pParse,
                                                  pX->pLeft, pX->pRight);
              if( pColl==0 ) pColl = pParse->db->pDfltColl;
              if( sqlite4_stricmp(pColl->zName, pScan->zCollName) ){
                continue;
              }
            }
            if( (pTerm->eOperator & WO_EQ)!=0
             && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
             && pX->iTable==pScan->aEquiv[0]
             && pX->iColumn==pScan->aEquiv[1]
            ){
              continue;
            }
            pScan->k = k+1;
            return pTerm;
          }
        }
      }
      pScan->pWC = pScan->pWC->pOuter;
      k = 0;
    }
    pScan->pWC = pScan->pOrigWC;
    k = 0;
    pScan->iEquiv += 2;
  }
  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( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
    iRet = pPk->aiColumn[iIdxCol - pIdx->nColumn];
  }
  return iRet;
}

/*
** Return a pointer to a buffer containing the name of the collation 
** sequence used with the iIdxCol'th field in index pIdx, including any
** appended PRIMARY KEY fields.
*/
static char *idxColumnCollation(Index *pIdx, Index *pPk, int iIdxCol){
  char *zColl;
  assert( iIdxCol<(pIdx->nColumn + pPk->nColumn) );
  if( iIdxCol<pIdx->nColumn ){
    zColl = pIdx->azColl[iIdxCol];
  }else if( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
    zColl = pPk->azColl[iIdxCol - pIdx->nColumn];
  }
  return zColl;
}

/*
** Return the sort order (SQLITE4_SO_ASC or DESC) used by the iIdxCol'th 
** field in index pIdx, including any appended PRIMARY KEY fields.
*/
static int idxColumnSortOrder(Index *pIdx, Index *pPk, int iIdxCol){
  int iRet = SQLITE4_SO_ASC;
  if( iIdxCol<pIdx->nColumn ){
    iRet = pIdx->aSortOrder[iIdxCol];
  }
  return iRet;
}

/*
** Return the total number of fields in the index pIdx, including any
** trailing primary key fields.
*/
static int idxColumnCount(Index *pIdx, Index *pPk){
  return (pIdx->nColumn + ((pPk==0 || pIdx==pPk) ? 0 : pPk->nColumn));
}

/*
** Initialize a WHERE clause scanner object.  Return a pointer to the
** first match.  Return NULL if there are no matches.
**
** The scanner will be searching the WHERE clause pWC.  It will look
** for terms of the form "X <op> <expr>" where X is column iColumn of table
** iCur.  The <op> must be one of the operators described by opMask.
**
** If the search is for X and the WHERE clause contains terms of the
** form X=Y then this routine might also return terms of the form
** "Y <op> <expr>".  The number of levels of transitivity is limited,
** but is enough to handle most commonly occurring SQL statements.
**
** If X is not the INTEGER PRIMARY KEY then X must be compatible with
** index pIdx.
*/
static WhereTerm *whereScanInit(
  WhereScan *pScan,       /* The WhereScan object being initialized */
  WhereClause *pWC,       /* The WHERE clause to be scanned */
  int iCur,               /* Cursor to scan for */
  int iColumn,            /* Column to scan for */
  u32 opMask,             /* Operator(s) to scan for */
  Index *pIdx             /* Must be compatible with this index */
){
  int j;

  /* memset(pScan, 0, sizeof(*pScan)); */
  pScan->pOrigWC = pWC;
  pScan->pWC = pWC;
  if( pIdx && iColumn>=0 ){
    Index *pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
    pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
    for(j=0; idxColumnNumber(pIdx, pPk, j)!=iColumn; j++){
      if( NEVER(j>=idxColumnCount(pIdx, pPk)) ) return 0;
    }
    pScan->zCollName = idxColumnCollation(pIdx, pPk, j);
  }else{
    pScan->idxaff = 0;
    pScan->zCollName = 0;
  }
  pScan->opMask = opMask;
  pScan->k = 0;
  pScan->aEquiv[0] = iCur;
  pScan->aEquiv[1] = iColumn;
  pScan->nEquiv = 2;
  pScan->iEquiv = 2;
  return whereScanNext(pScan);
}

/*
** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
** where X is a reference to the iColumn of table iCur and <op> is one of
** the WO_xx operator codes specified by the op parameter.
** Return a pointer to the term.  Return 0 if not found.
**
** The term returned might by Y=<expr> if there is another constraint in
** the WHERE clause that specifies that X=Y.  Any such constraints will be
** identified by the WO_EQUIV bit in the pTerm->eOperator field.  The
** aEquiv[] array holds X and all its equivalents, with each SQL variable
** taking up two slots in aEquiv[].  The first slot is for the cursor number
** and the second is for the column number.  There are 22 slots in aEquiv[]
** so that means we can look for X plus up to 10 other equivalent values.
** Hence a search for X will return <expr> if X=A1 and A1=A2 and A2=A3
** and ... and A9=A10 and A10=<expr>.
**
** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
** then try for the one with no dependencies on <expr> - in other words where
** <expr> is a constant expression of some kind.  Only return entries of
** the form "X <op> Y" where Y is a column in another table if no terms of
** the form "X <op> <const-expr>" exist.   If no terms with a constant RHS
** exist, try to return a term that does not use WO_EQUIV.
*/
static WhereTerm *findTerm(
  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 *pResult = 0;
  WhereTerm *p;
  WhereScan scan;

  p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
  while( p ){



    if( (p->prereqRight & notReady)==0 ){

      if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){








        return p;


      }
      if( pResult==0 ) pResult = p;










    }
    p = whereScanNext(&scan);



  }
  return pResult;




}

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








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




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









|
|
|

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







>
>
>
>
>







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
  assert( op!=TK_LT || c==WO_LT );
  assert( op!=TK_LE || c==WO_LE );
  assert( op!=TK_GT || c==WO_GT );
  assert( op!=TK_GE || c==WO_GE );
  return c;
}

/*

























































































































































































** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
** where X is a reference to the iColumn of table iCur and <op> is one of
** the WO_xx operator codes specified by the op parameter.
** Return a pointer to the term.  Return 0 if not found.

















*/
static WhereTerm *findTerm(
  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);
          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, 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--){
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
    return 0;
  }
#ifdef SQLITE4_EBCDIC
  if( *pnoCase ) return 0;
#endif
  pList = pExpr->x.pList;
  pLeft = pList->a[1].pExpr;
  if( pLeft->op!=TK_COLUMN 
   || sqlite4ExprAffinity(pLeft)!=SQLITE4_AFF_TEXT 
   || IsVirtual(pLeft->pTab)
  ){
    /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
    ** be the name of an indexed column with TEXT affinity. */
    return 0;
  }
  assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */

  pRight = pList->a[0].pExpr;
  op = pRight->op;
  if( op==TK_REGISTER ){
    op = pRight->op2;
  }
  if( op==TK_VARIABLE ){
    Vdbe *pReprepare = pParse->pReprepare;
    int iCol = pRight->iColumn;
    pVal = sqlite4VdbeGetValue(pReprepare, iCol, SQLITE4_AFF_NONE);
    if( pVal && sqlite4_value_type(pVal)==SQLITE4_TEXT ){
      z = (char *)sqlite4_value_text(pVal, 0);
    }
    sqlite4VdbeSetVarmask(pParse->pVdbe, iCol);
    assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
  }else if( op==TK_STRING ){
    z = pRight->u.zToken;
  }
  if( z ){







<
|
<
<
















|







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
    return 0;
  }
#ifdef SQLITE4_EBCDIC
  if( *pnoCase ) return 0;
#endif
  pList = pExpr->x.pList;
  pLeft = pList->a[1].pExpr;

  if( pLeft->op!=TK_COLUMN || sqlite4ExprAffinity(pLeft)!=SQLITE4_AFF_TEXT ){


    /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
    ** be the name of an indexed column with TEXT affinity. */
    return 0;
  }
  assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */

  pRight = pList->a[0].pExpr;
  op = pRight->op;
  if( op==TK_REGISTER ){
    op = pRight->op2;
  }
  if( op==TK_VARIABLE ){
    Vdbe *pReprepare = pParse->pReprepare;
    int iCol = pRight->iColumn;
    pVal = sqlite4VdbeGetValue(pReprepare, iCol, SQLITE4_AFF_NONE);
    if( pVal && sqlite4_value_type(pVal)==SQLITE4_TEXT ){
      z = sqlite4_value_text(pVal, 0);
    }
    sqlite4VdbeSetVarmask(pParse->pVdbe, iCol);
    assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
  }else if( op==TK_STRING ){
    z = pRight->u.zToken;
  }
  if( z ){
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
**     (B)     x=expr1 OR expr2=x OR x=expr3
**     (C)     t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
**     (D)     x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
**     (E)     (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
**
** CASE 1:
**
** If all subterms are of the form T.C=expr for some single column of C and
** a single table T (as shown in example B above) then create a new virtual
** term that is an equivalent IN expression.  In other words, if the term
** being analyzed is:
**
**      x = expr1  OR  expr2 = x  OR  x = expr3
**
** then create a new virtual term like this:







|







821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
**     (B)     x=expr1 OR expr2=x OR x=expr3
**     (C)     t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
**     (D)     x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
**     (E)     (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
**
** CASE 1:
**
** If all subterms are of the form T.C=expr for some single column of C
** a single table T (as shown in example B above) then create a new virtual
** term that is an equivalent IN expression.  In other words, if the term
** being analyzed is:
**
**      x = expr1  OR  expr2 = x  OR  x = expr3
**
** then create a new virtual term like this:
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
** zero.  This term is not useful for search.
*/
static void exprAnalyzeOrTerm(
  SrcList *pSrc,            /* the FROM clause */
  WhereClause *pWC,         /* the complete WHERE clause */
  int idxTerm               /* Index of the OR-term to be analyzed */
){
  WhereInfo *pWInfo = pWC->pWInfo;        /* WHERE clause processing context */
  Parse *pParse = pWInfo->pParse;         /* Parser context */
  sqlite4 *db = pParse->db;               /* Database connection */
  WhereTerm *pTerm = &pWC->a[idxTerm];    /* The term to be analyzed */
  Expr *pExpr = pTerm->pExpr;             /* The expression of the term */

  int i;                                  /* Loop counters */
  WhereClause *pOrWc;       /* Breakup of pTerm into subterms */
  WhereTerm *pOrTerm;       /* A Sub-term within the pOrWc */
  WhereOrInfo *pOrInfo;     /* Additional information associated with pTerm */
  Bitmask chngToIN;         /* Tables that might satisfy case 1 */
  Bitmask indexable;        /* Tables that are indexable, satisfying case 2 */

  /*
  ** Break the OR clause into its separate subterms.  The subterms are
  ** stored in a WhereClause structure containing within the WhereOrInfo
  ** object that is attached to the original OR clause term.
  */
  assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 );
  assert( pExpr->op==TK_OR );
  pTerm->u.pOrInfo = pOrInfo = sqlite4DbMallocZero(db, sizeof(*pOrInfo));
  if( pOrInfo==0 ) return;
  pTerm->wtFlags |= TERM_ORINFO;
  pOrWc = &pOrInfo->wc;
  whereClauseInit(pOrWc, pWInfo);
  whereSplit(pOrWc, pExpr, TK_OR);
  exprAnalyzeAll(pSrc, pOrWc);
  if( db->mallocFailed ) return;
  assert( pOrWc->nTerm>=2 );

  /*
  ** Compute the set of tables that might satisfy cases 1 or 2.
  */
  indexable = ~(Bitmask)0;
  chngToIN = ~(Bitmask)0;
  for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
    if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
      WhereAndInfo *pAndInfo;

      assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
      chngToIN = 0;
      pAndInfo = sqlite4DbMallocRaw(db, sizeof(*pAndInfo));
      if( pAndInfo ){
        WhereClause *pAndWC;
        WhereTerm *pAndTerm;
        int j;
        Bitmask b = 0;
        pOrTerm->u.pAndInfo = pAndInfo;
        pOrTerm->wtFlags |= TERM_ANDINFO;
        pOrTerm->eOperator = WO_AND;
        pAndWC = &pAndInfo->wc;
        whereClauseInit(pAndWC, pWC->pWInfo);
        whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
        exprAnalyzeAll(pSrc, pAndWC);
        pAndWC->pOuter = pWC;
        testcase( db->mallocFailed );
        if( !db->mallocFailed ){
          for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
            assert( pAndTerm->pExpr );
            if( allowedOp(pAndTerm->pExpr->op) ){
              b |= getMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
            }
          }
        }
        indexable &= b;
      }
    }else if( pOrTerm->wtFlags & TERM_COPIED ){
      /* Skip this term for now.  We revisit it when we process the
      ** corresponding TERM_VIRTUAL term */
    }else{
      Bitmask b;
      b = getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor);
      if( pOrTerm->wtFlags & TERM_VIRTUAL ){
        WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
        b |= getMask(&pWInfo->sMaskSet, pOther->leftCursor);
      }
      indexable &= b;
      if( (pOrTerm->eOperator & WO_EQ)==0 ){
        chngToIN = 0;
      }else{
        chngToIN &= b;
      }
    }
  }








<
|



>


















|









|



>












|








|










|


|


|







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
** zero.  This term is not useful for search.
*/
static void exprAnalyzeOrTerm(
  SrcList *pSrc,            /* the FROM clause */
  WhereClause *pWC,         /* the complete WHERE clause */
  int idxTerm               /* Index of the OR-term to be analyzed */
){

  Parse *pParse = pWC->pParse;            /* Parser context */
  sqlite4 *db = pParse->db;               /* Database connection */
  WhereTerm *pTerm = &pWC->a[idxTerm];    /* The term to be analyzed */
  Expr *pExpr = pTerm->pExpr;             /* The expression of the term */
  WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */
  int i;                                  /* Loop counters */
  WhereClause *pOrWc;       /* Breakup of pTerm into subterms */
  WhereTerm *pOrTerm;       /* A Sub-term within the pOrWc */
  WhereOrInfo *pOrInfo;     /* Additional information associated with pTerm */
  Bitmask chngToIN;         /* Tables that might satisfy case 1 */
  Bitmask indexable;        /* Tables that are indexable, satisfying case 2 */

  /*
  ** Break the OR clause into its separate subterms.  The subterms are
  ** stored in a WhereClause structure containing within the WhereOrInfo
  ** object that is attached to the original OR clause term.
  */
  assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 );
  assert( pExpr->op==TK_OR );
  pTerm->u.pOrInfo = pOrInfo = sqlite4DbMallocZero(db, sizeof(*pOrInfo));
  if( pOrInfo==0 ) return;
  pTerm->wtFlags |= TERM_ORINFO;
  pOrWc = &pOrInfo->wc;
  whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
  whereSplit(pOrWc, pExpr, TK_OR);
  exprAnalyzeAll(pSrc, pOrWc);
  if( db->mallocFailed ) return;
  assert( pOrWc->nTerm>=2 );

  /*
  ** Compute the set of tables that might satisfy cases 1 or 2.
  */
  indexable = ~(Bitmask)0;
  chngToIN = ~(pWC->vmask);
  for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
    if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
      WhereAndInfo *pAndInfo;
      assert( pOrTerm->eOperator==0 );
      assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
      chngToIN = 0;
      pAndInfo = sqlite4DbMallocRaw(db, sizeof(*pAndInfo));
      if( pAndInfo ){
        WhereClause *pAndWC;
        WhereTerm *pAndTerm;
        int j;
        Bitmask b = 0;
        pOrTerm->u.pAndInfo = pAndInfo;
        pOrTerm->wtFlags |= TERM_ANDINFO;
        pOrTerm->eOperator = WO_AND;
        pAndWC = &pAndInfo->wc;
        whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
        whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
        exprAnalyzeAll(pSrc, pAndWC);
        pAndWC->pOuter = pWC;
        testcase( db->mallocFailed );
        if( !db->mallocFailed ){
          for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
            assert( pAndTerm->pExpr );
            if( allowedOp(pAndTerm->pExpr->op) ){
              b |= getMask(pMaskSet, pAndTerm->leftCursor);
            }
          }
        }
        indexable &= b;
      }
    }else if( pOrTerm->wtFlags & TERM_COPIED ){
      /* Skip this term for now.  We revisit it when we process the
      ** corresponding TERM_VIRTUAL term */
    }else{
      Bitmask b;
      b = getMask(pMaskSet, pOrTerm->leftCursor);
      if( pOrTerm->wtFlags & TERM_VIRTUAL ){
        WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
        b |= getMask(pMaskSet, pOther->leftCursor);
      }
      indexable &= b;
      if( pOrTerm->eOperator!=WO_EQ ){
        chngToIN = 0;
      }else{
        chngToIN &= b;
      }
    }
  }

1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
    ** will be recorded in iCursor and iColumn.  There might not be any
    ** such table and column.  Set okToChngToIN if an appropriate table
    ** and column is found but leave okToChngToIN false if not found.
    */
    for(j=0; j<2 && !okToChngToIN; j++){
      pOrTerm = pOrWc->a;
      for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
        assert( pOrTerm->eOperator & WO_EQ );
        pOrTerm->wtFlags &= ~TERM_OR_OK;
        if( pOrTerm->leftCursor==iCursor ){
          /* This is the 2-bit case and we are on the second iteration and
          ** current term is from the first iteration.  So skip this term. */
          assert( j==1 );
          continue;
        }
        if( (chngToIN & getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){
          /* This term must be of the form t1.a==t2.b where t2 is in the
          ** chngToIN set but t1 is not.  This term will be either preceeded
          ** or follwed by an inverted copy (t2.b==t1.a).  Skip this term 
          ** and use its inversion. */
          testcase( pOrTerm->wtFlags & TERM_COPIED );
          testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
          assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
          continue;
        }
        iColumn = pOrTerm->u.leftColumn;
        iCursor = pOrTerm->leftCursor;
        break;
      }
      if( i<0 ){
        /* No candidate table+column was found.  This can only occur
        ** on the second iteration */
        assert( j==1 );
        assert( IsPowerOfTwo(chngToIN) );
        assert( chngToIN==getMask(&pWInfo->sMaskSet, iCursor) );
        break;
      }
      testcase( j==1 );

      /* We have found a candidate table and column.  Check to see if that
      ** table and column is common to every term in the OR clause */
      okToChngToIN = 1;
      for(; i>=0 && okToChngToIN; i--, pOrTerm++){
        assert( pOrTerm->eOperator & WO_EQ );
        if( pOrTerm->leftCursor!=iCursor ){
          pOrTerm->wtFlags &= ~TERM_OR_OK;
        }else if( pOrTerm->u.leftColumn!=iColumn ){
          okToChngToIN = 0;
        }else{
          int affLeft, affRight;
          /* If the right-hand side is also a column, then the affinities







|







|

















|
|








|







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
    ** will be recorded in iCursor and iColumn.  There might not be any
    ** such table and column.  Set okToChngToIN if an appropriate table
    ** and column is found but leave okToChngToIN false if not found.
    */
    for(j=0; j<2 && !okToChngToIN; j++){
      pOrTerm = pOrWc->a;
      for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
        assert( pOrTerm->eOperator==WO_EQ );
        pOrTerm->wtFlags &= ~TERM_OR_OK;
        if( pOrTerm->leftCursor==iCursor ){
          /* This is the 2-bit case and we are on the second iteration and
          ** current term is from the first iteration.  So skip this term. */
          assert( j==1 );
          continue;
        }
        if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
          /* This term must be of the form t1.a==t2.b where t2 is in the
          ** chngToIN set but t1 is not.  This term will be either preceeded
          ** or follwed by an inverted copy (t2.b==t1.a).  Skip this term 
          ** and use its inversion. */
          testcase( pOrTerm->wtFlags & TERM_COPIED );
          testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
          assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
          continue;
        }
        iColumn = pOrTerm->u.leftColumn;
        iCursor = pOrTerm->leftCursor;
        break;
      }
      if( i<0 ){
        /* No candidate table+column was found.  This can only occur
        ** on the second iteration */
        assert( j==1 );
        assert( (chngToIN&(chngToIN-1))==0 );
        assert( chngToIN==getMask(pMaskSet, iCursor) );
        break;
      }
      testcase( j==1 );

      /* We have found a candidate table and column.  Check to see if that
      ** table and column is common to every term in the OR clause */
      okToChngToIN = 1;
      for(; i>=0 && okToChngToIN; i--, pOrTerm++){
        assert( pOrTerm->eOperator==WO_EQ );
        if( pOrTerm->leftCursor!=iCursor ){
          pOrTerm->wtFlags &= ~TERM_OR_OK;
        }else if( pOrTerm->u.leftColumn!=iColumn ){
          okToChngToIN = 0;
        }else{
          int affLeft, affRight;
          /* If the right-hand side is also a column, then the affinities
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
      Expr *pDup;            /* A transient duplicate expression */
      ExprList *pList = 0;   /* The RHS of the IN operator */
      Expr *pLeft = 0;       /* The LHS of the IN operator */
      Expr *pNew;            /* The complete IN operator */

      for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
        assert( pOrTerm->eOperator & WO_EQ );
        assert( pOrTerm->leftCursor==iCursor );
        assert( pOrTerm->u.leftColumn==iColumn );
        pDup = sqlite4ExprDup(db, pOrTerm->pExpr->pRight, 0);
        pList = sqlite4ExprListAppend(pWInfo->pParse, pList, pDup);
        pLeft = pOrTerm->pExpr->pLeft;
      }
      assert( pLeft!=0 );
      pDup = sqlite4ExprDup(db, pLeft, 0);
      pNew = sqlite4PExpr(pParse, TK_IN, pDup, 0, 0);
      if( pNew ){
        int idxNew;







|



|







1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
      Expr *pDup;            /* A transient duplicate expression */
      ExprList *pList = 0;   /* The RHS of the IN operator */
      Expr *pLeft = 0;       /* The LHS of the IN operator */
      Expr *pNew;            /* The complete IN operator */

      for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
        assert( pOrTerm->eOperator==WO_EQ );
        assert( pOrTerm->leftCursor==iCursor );
        assert( pOrTerm->u.leftColumn==iColumn );
        pDup = sqlite4ExprDup(db, pOrTerm->pExpr->pRight, 0);
        pList = sqlite4ExprListAppend(pWC->pParse, pList, pDup);
        pLeft = pOrTerm->pExpr->pLeft;
      }
      assert( pLeft!=0 );
      pDup = sqlite4ExprDup(db, pLeft, 0);
      pNew = sqlite4PExpr(pParse, TK_IN, pDup, 0, 0);
      if( pNew ){
        int idxNew;
1608
1609
1610
1611
1612
1613
1614

1615
1616
1617
1618
1619
1620
1621
        sqlite4ExprListDelete(db, pList);
      }
      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 2 */
    }
  }
}
#endif /* !SQLITE4_OMIT_OR_OPTIMIZATION && !SQLITE4_OMIT_SUBQUERY */


/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**







>







1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
        sqlite4ExprListDelete(db, pList);
      }
      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 2 */
    }
  }
}
#endif /* !SQLITE4_OMIT_OR_OPTIMIZATION && !SQLITE4_OMIT_SUBQUERY */


/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**
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
** and the copy has idxParent set to the index of the original term.
*/
static void exprAnalyze(
  SrcList *pSrc,            /* the FROM clause */
  WhereClause *pWC,         /* the WHERE clause */
  int idxTerm               /* Index of the term to be analyzed */
){
  WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */
  WhereTerm *pTerm;                /* The term to be analyzed */
  WhereMaskSet *pMaskSet;          /* Set of table index masks */
  Expr *pExpr;                     /* The expression to be analyzed */
  Bitmask prereqLeft;              /* Prerequesites of the pExpr->pLeft */
  Bitmask prereqAll;               /* Prerequesites of pExpr */
  Bitmask extraRight = 0;          /* Extra dependencies on LEFT JOIN */
  Expr *pStr1 = 0;                 /* RHS of LIKE/GLOB operator */
  int isComplete = 0;              /* RHS of LIKE/GLOB ends with wildcard */
  int noCase = 0;                  /* LIKE/GLOB distinguishes case */
  int op;                          /* Top-level operator.  pExpr->op */
  Parse *pParse = pWInfo->pParse;  /* Parsing context */
  sqlite4 *db = pParse->db;        /* Database connection */

  if( db->mallocFailed ){
    return;
  }
  pTerm = &pWC->a[idxTerm];
  pMaskSet = &pWInfo->sMaskSet;
  pExpr = pTerm->pExpr;
  assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  op = pExpr->op;
  if( op==TK_IN ){
    assert( pExpr->pRight==0 );
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
      pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
    }else{







<










|






|

<







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
** and the copy has idxParent set to the index of the original term.
*/
static void exprAnalyze(
  SrcList *pSrc,            /* the FROM clause */
  WhereClause *pWC,         /* the WHERE clause */
  int idxTerm               /* Index of the term to be analyzed */
){

  WhereTerm *pTerm;                /* The term to be analyzed */
  WhereMaskSet *pMaskSet;          /* Set of table index masks */
  Expr *pExpr;                     /* The expression to be analyzed */
  Bitmask prereqLeft;              /* Prerequesites of the pExpr->pLeft */
  Bitmask prereqAll;               /* Prerequesites of pExpr */
  Bitmask extraRight = 0;          /* Extra dependencies on LEFT JOIN */
  Expr *pStr1 = 0;                 /* RHS of LIKE/GLOB operator */
  int isComplete = 0;              /* RHS of LIKE/GLOB ends with wildcard */
  int noCase = 0;                  /* LIKE/GLOB distinguishes case */
  int op;                          /* Top-level operator.  pExpr->op */
  Parse *pParse = pWC->pParse;     /* Parsing context */
  sqlite4 *db = pParse->db;        /* Database connection */

  if( db->mallocFailed ){
    return;
  }
  pTerm = &pWC->a[idxTerm];
  pMaskSet = pWC->pMaskSet;
  pExpr = pTerm->pExpr;

  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  op = pExpr->op;
  if( op==TK_IN ){
    assert( pExpr->pRight==0 );
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
      pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
    }else{
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
    extraRight = x-1;  /* ON clause terms may not be used with an index
                       ** on left table of a LEFT JOIN.  Ticket #3015 */
  }
  pTerm->prereqAll = prereqAll;
  pTerm->leftCursor = -1;
  pTerm->iParent = -1;
  pTerm->eOperator = 0;
  if( allowedOp(op) ){
    Expr *pLeft = sqlite4ExprSkipCollate(pExpr->pLeft);
    Expr *pRight = sqlite4ExprSkipCollate(pExpr->pRight);
    u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
    if( pLeft->op==TK_COLUMN ){
      pTerm->leftCursor = pLeft->iTable;
      pTerm->u.leftColumn = pLeft->iColumn;
      pTerm->eOperator = operatorMask(op) & opMask;
    }
    if( pRight && pRight->op==TK_COLUMN ){
      WhereTerm *pNew;
      Expr *pDup;
      u16 eExtraOp = 0;        /* Extra bits for pNew->eOperator */
      if( pTerm->leftCursor>=0 ){
        int idxNew;
        pDup = sqlite4ExprDup(db, pExpr, 0);
        if( db->mallocFailed ){
          sqlite4ExprDelete(db, pDup);
          return;
        }
        idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
        if( idxNew==0 ) return;
        pNew = &pWC->a[idxNew];
        pNew->iParent = idxTerm;
        pTerm = &pWC->a[idxTerm];
        pTerm->nChild = 1;
        pTerm->wtFlags |= TERM_COPIED;
        if( pExpr->op==TK_EQ
         && !ExprHasProperty(pExpr, EP_FromJoin)
         && OptimizationEnabled(db, SQLITE4_Transitive)
        ){
          pTerm->eOperator |= WO_EQUIV;
          eExtraOp = WO_EQUIV;
        }
      }else{
        pDup = pExpr;
        pNew = pTerm;
      }
      exprCommute(pParse, pDup);
      pLeft = sqlite4ExprSkipCollate(pDup->pLeft);
      pNew->leftCursor = pLeft->iTable;
      pNew->u.leftColumn = pLeft->iColumn;
      testcase( (prereqLeft | extraRight) != prereqLeft );
      pNew->prereqRight = prereqLeft | extraRight;
      pNew->prereqAll = prereqAll;
      pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
    }
  }

#ifndef SQLITE4_OMIT_BETWEEN_OPTIMIZATION
  /* If a term is the BETWEEN operator, create two new virtual terms
  ** that define the range that the BETWEEN implements.  For example:
  **







|
|
|
<



|




<














<
<
<
<
<
<
<





|





|







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
    extraRight = x-1;  /* ON clause terms may not be used with an index
                       ** on left table of a LEFT JOIN.  Ticket #3015 */
  }
  pTerm->prereqAll = prereqAll;
  pTerm->leftCursor = -1;
  pTerm->iParent = -1;
  pTerm->eOperator = 0;
  if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
    Expr *pLeft = pExpr->pLeft;
    Expr *pRight = pExpr->pRight;

    if( pLeft->op==TK_COLUMN ){
      pTerm->leftCursor = pLeft->iTable;
      pTerm->u.leftColumn = pLeft->iColumn;
      pTerm->eOperator = operatorMask(op);
    }
    if( pRight && pRight->op==TK_COLUMN ){
      WhereTerm *pNew;
      Expr *pDup;

      if( pTerm->leftCursor>=0 ){
        int idxNew;
        pDup = sqlite4ExprDup(db, pExpr, 0);
        if( db->mallocFailed ){
          sqlite4ExprDelete(db, pDup);
          return;
        }
        idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
        if( idxNew==0 ) return;
        pNew = &pWC->a[idxNew];
        pNew->iParent = idxTerm;
        pTerm = &pWC->a[idxTerm];
        pTerm->nChild = 1;
        pTerm->wtFlags |= TERM_COPIED;







      }else{
        pDup = pExpr;
        pNew = pTerm;
      }
      exprCommute(pParse, pDup);
      pLeft = pDup->pLeft;
      pNew->leftCursor = pLeft->iTable;
      pNew->u.leftColumn = pLeft->iColumn;
      testcase( (prereqLeft | extraRight) != prereqLeft );
      pNew->prereqRight = prereqLeft | extraRight;
      pNew->prereqAll = prereqAll;
      pNew->eOperator = operatorMask(pDup->op);
    }
  }

#ifndef SQLITE4_OMIT_BETWEEN_OPTIMIZATION
  /* If a term is the BETWEEN operator, create two new virtual terms
  ** that define the range that the BETWEEN implements.  For example:
  **
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
  ){
    Expr *pLeft;       /* LHS of LIKE/GLOB operator */
    Expr *pStr2;       /* Copy of pStr1 - RHS of LIKE/GLOB operator */
    Expr *pNewExpr1;
    Expr *pNewExpr2;
    int idxNew1;
    int idxNew2;
    Token sCollSeqName;  /* Name of collating sequence */

    pLeft = pExpr->x.pList->a[1].pExpr;
    pStr2 = sqlite4ExprDup(db, pStr1, 0);
    if( !db->mallocFailed ){
      u8 c, *pC;       /* Last character before the first wildcard */
      pC = (u8*)&pStr2->u.zToken[sqlite4Strlen30(pStr2->u.zToken)-1];
      c = *pC;







|







1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
  ){
    Expr *pLeft;       /* LHS of LIKE/GLOB operator */
    Expr *pStr2;       /* Copy of pStr1 - RHS of LIKE/GLOB operator */
    Expr *pNewExpr1;
    Expr *pNewExpr2;
    int idxNew1;
    int idxNew2;
    CollSeq *pColl;    /* Collating sequence to use */

    pLeft = pExpr->x.pList->a[1].pExpr;
    pStr2 = sqlite4ExprDup(db, pStr1, 0);
    if( !db->mallocFailed ){
      u8 c, *pC;       /* Last character before the first wildcard */
      pC = (u8*)&pStr2->u.zToken[sqlite4Strlen30(pStr2->u.zToken)-1];
      c = *pC;
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
        if( c=='A'-1 ) isComplete = 0;   /* EV: R-64339-08207 */


        c = sqlite4UpperToLower[c];
      }
      *pC = c + 1;
    }
    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
    sCollSeqName.n = 6;
    pNewExpr1 = sqlite4ExprDup(db, pLeft, 0);
    sqlite4ExprSetCollByToken(pParse, pNewExpr1, &sCollSeqName);
    pNewExpr1 = sqlite4PExpr(pParse, TK_GE, pNewExpr1, pStr1, 0);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew1==0 );
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite4ExprDup(db, pLeft, 0);
    sqlite4ExprSetCollByToken(pParse, pNewExpr2, &sCollSeqName);
    pNewExpr2 = sqlite4PExpr(pParse, TK_LT, pNewExpr2, pStr2, 0);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;







|
<
|
|
|



|
|
|







1304
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
        if( c=='A'-1 ) isComplete = 0;   /* EV: R-64339-08207 */


        c = sqlite4UpperToLower[c];
      }
      *pC = c + 1;
    }
    pColl = sqlite4FindCollSeq(db, noCase ? "NOCASE" : "BINARY",0);

    pNewExpr1 = sqlite4PExpr(pParse, TK_GE, 
                     sqlite4ExprSetColl(sqlite4ExprDup(db,pLeft,0), pColl),
                     pStr1, 0);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew1==0 );
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite4PExpr(pParse, TK_LT,
                     sqlite4ExprSetColl(sqlite4ExprDup(db,pLeft,0), pColl),
                     pStr2, 0);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
  ** TERM_VNULL tag will suppress the not-null check at the beginning
  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  ** the start of the loop will prevent any results from being returned.
  */
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0
   && OptimizationEnabled(db, SQLITE4_Stat3)
  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite4PExpr(pParse, TK_GT,







<







1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
  ** TERM_VNULL tag will suppress the not-null check at the beginning
  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  ** the start of the loop will prevent any results from being returned.
  */
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0

  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite4PExpr(pParse, TK_GT,
1927
1928
1929
1930
1931
1932
1933



















1934

1935


1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
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
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032

2033






















2034








2035




2036



2037









2038
2039
2040

2041
2042

2043
2044
2045


2046
2047
2048
2049



2050
2051
2052
2053
2054
2055




2056


2057



2058




2059







2060







2061

2062
2063
2064
2065
2066
2067


2068

2069

2070
2071

2072



2073





2074





2075


2076









2077









2078
2079
2080
2081
2082
2083
2084
2085
2086
2087



2088
2089
2090
2091
2092


2093





2094
2095







2096





2097
2098




2099
2100

2101




2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  pTerm->prereqRight |= extraRight;
}

/*



















** This function searches pList for a entry that matches the iCol-th column

** of index pIdx.


**
** If such an expression is found, its index in pList->a[] is returned. If
** no expression is found, -1 is returned.
*/
static int findIndexCol(
  Parse *pParse,                  /* Parse context */
  ExprList *pList,                /* Expression list to search */
  int iBase,                      /* Cursor for table associated with pIdx */
  Index *pIdx,                    /* Index to match column of */
  int iCol                        /* Column of index to match */
){
  int i;
  const char *zColl = pIdx->azColl[iCol];

  for(i=0; i<pList->nExpr; i++){
    Expr *p = sqlite4ExprSkipCollate(pList->a[i].pExpr);
    if( p->op==TK_COLUMN
     && p->iColumn==pIdx->aiColumn[iCol]
     && p->iTable==iBase
    ){
      CollSeq *pColl = sqlite4ExprCollSeq(pParse, pList->a[i].pExpr);

      if( ALWAYS(pColl) && 0==sqlite4_stricmp(pColl->zName, zColl) ){
        return i;
      }
    }
  }

  return -1;
}

/*



** Return true if the DISTINCT expression-list passed as the third argument
** is redundant.

**





















































** A DISTINCT list is redundant if the database contains some subset of
** columns that are unique and non-null.

*/
static int isDistinctRedundant(
  Parse *pParse,            /* Parsing context */
  SrcList *pTabList,        /* The FROM clause */
  WhereClause *pWC,         /* The WHERE clause */
  ExprList *pDistinct       /* The result set that needs to be DISTINCT */
){
  Table *pTab;
  Index *pIdx;
  int i;                          
  int iBase;

  /* If there is more than one table or sub-select in the FROM clause of
  ** this query, then it will not be possible to show that the DISTINCT 
  ** clause is redundant. */
  if( pTabList->nSrc!=1 ) return 0;
  iBase = pTabList->a[0].iCursor;
  pTab = pTabList->a[0].pTab;

  /* If any of the expressions is an IPK column on table iBase, then return 
  ** true. Note: The (p->iTable==iBase) part of this test may be false if the
  ** current SELECT is a correlated sub-query.
  */
  for(i=0; i<pDistinct->nExpr; i++){
    Expr *p = sqlite4ExprSkipCollate(pDistinct->a[i].pExpr);
    if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
  }

  /* Loop through all indices on the table, checking each to see if it makes
  ** the DISTINCT qualifier redundant. It does so if:
  **
  **   1. The index is itself UNIQUE, and
  **
  **   2. All of the columns in the index are either part of the pDistinct
  **      list, or else the WHERE clause contains a term of the form "col=X",
  **      where X is a constant value. The collation sequences of the
  **      comparison and select-list expressions must match those of the index.
  **
  **   3. All of those index columns for which the WHERE clause does not
  **      contain a "col=X" term are subject to a NOT NULL constraint.
  */
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    if( pIdx->onError==OE_None ) continue;
    for(i=0; i<pIdx->nColumn; i++){
      int iCol = pIdx->aiColumn[i];
      if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
        int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
        if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
          break;
        }
      }
    }
    if( i==pIdx->nColumn ){
      /* This index implies that the DISTINCT qualifier is redundant. */
      return 1;
    }
  }

  return 0;
}


/* 






















** The (an approximate) sum of two WhereCosts.  This computation is








** not a simple "+" operator because WhereCost is stored as a logarithmic




** value.



** 









*/
static WhereCost whereCostAdd(WhereCost a, WhereCost b){
  static const unsigned char x[] = {

     10, 10,                         /* 0,1 */
      9, 9,                          /* 2,3 */

      8, 8,                          /* 4,5 */
      7, 7, 7,                       /* 6,7,8 */
      6, 6, 6,                       /* 9,10,11 */


      5, 5, 5,                       /* 12-14 */
      4, 4, 4, 4,                    /* 15-18 */
      3, 3, 3, 3, 3, 3,              /* 19-24 */
      2, 2, 2, 2, 2, 2, 2,           /* 25-31 */



  };
  if( a>=b ){
    if( a>b+49 ) return a;
    if( a>b+31 ) return a+1;
    return a+x[a-b];
  }else{




    if( b>a+49 ) return b;


    if( b>a+31 ) return b+1;



    return b+x[b-a];




  }







}









/*
** Convert an integer into a WhereCost.  In other words, compute a
** good approximatation for 10*log2(x).
*/
static WhereCost whereCost(tRowcnt x){
  static WhereCost a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };


  WhereCost y = 40;

  if( x<8 ){

    if( x<2 ) return 0;
    while( x<8 ){  y -= 10; x <<= 1; }

  }else{



    while( x>255 ){ y += 40; x >>= 4; }





    while( x>15 ){  y += 10; x >>= 1; }





  }


  return a[x&7] + y - 10;









}










#ifndef SQLITE4_OMIT_VIRTUALTABLE
/*
** Convert a double (as received from xBestIndex of a virtual table)
** into a WhereCost.  In other words, compute an approximation for
** 10*log2(x).
*/
static WhereCost whereCostFromDouble(double x){
  u64 a;
  WhereCost e;



  assert( sizeof(x)==8 && sizeof(a)==8 );
  if( x<=1 ) return 0;
  if( x<=2000000000 ) return whereCost((tRowcnt)x);
  memcpy(&a, &x, 8);
  e = (a>>52) - 1022;


  return e*10;





}
#endif /* SQLITE4_OMIT_VIRTUALTABLE */













/*
** Estimate the logarithm of the input value to base 2.




*/
static WhereCost estLog(WhereCost N){

  WhereCost x = whereCost(N);




  return x>33 ? x - 33 : 0;
}

/*
** Two routines for printing the content of an sqlite4_index_info
** structure.  Used for testing and debugging only.  If neither
** SQLITE4_TEST or SQLITE4_DEBUG are defined, then these routines
** are no-ops.
*/
#if !defined(SQLITE4_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
static void TRACE_IDX_INPUTS(sqlite4_index_info *p){
  int i;
  if( !sqlite4WhereTrace ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite4DebugPrintf("  constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
       i,
       p->aConstraint[i].iColumn,







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















|




|
>
|









>
>
>
|
|
>

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


|
|
|
|


















|












<
<
<





|
|
|
|
<











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

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

|
>
>
>
>

|
>
|
>
>
>
>
|








|







1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573



1574
1575
1576
1577
1578
1579
1580
1581
1582

1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
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
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
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  pTerm->prereqRight |= extraRight;
}

/*
** Return TRUE if any of the expressions in pList->a[iFirst...] contain
** a reference to any table other than the iBase table.
*/
static int referencesOtherTables(
  ExprList *pList,          /* Search expressions in ths list */
  WhereMaskSet *pMaskSet,   /* Mapping from tables to bitmaps */
  int iFirst,               /* Be searching with the iFirst-th expression */
  int iBase                 /* Ignore references to this table */
){
  Bitmask allowed = ~getMask(pMaskSet, iBase);
  while( iFirst<pList->nExpr ){
    if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
      return 1;
    }
  }
  return 0;
}

/*
** This function searches the expression list passed as the second argument
** for an expression of type TK_COLUMN that refers to the same column and
** uses the same collation sequence as the iCol'th column of index pIdx.
** Argument iBase is the cursor number used for the table that pIdx refers
** to.
**
** If such an expression is found, its index in pList->a[] is returned. If
** no expression is found, -1 is returned.
*/
static int findIndexCol(
  Parse *pParse,                  /* Parse context */
  ExprList *pList,                /* Expression list to search */
  int iBase,                      /* Cursor for table associated with pIdx */
  Index *pIdx,                    /* Index to match column of */
  int iCol                        /* Column of index to match */
){
  int i;
  const char *zColl = pIdx->azColl[iCol];

  for(i=0; i<pList->nExpr; i++){
    Expr *p = pList->a[i].pExpr;
    if( p->op==TK_COLUMN
     && p->iColumn==pIdx->aiColumn[iCol]
     && p->iTable==iBase
    ){
      CollSeq *pColl = sqlite4ExprCollSeq(pParse, p);
      assert( pColl || p->iColumn==-1 );
      if( 0==pColl || 0==sqlite4_stricmp(pColl->zName, zColl) ){
        return i;
      }
    }
  }

  return -1;
}

/*
** This routine determines if pIdx can be used to assist in processing a
** DISTINCT qualifier. In other words, it tests whether or not using this
** index for the outer loop guarantees that rows with equal values for
** all expressions in the pDistinct list are delivered grouped together.
**
** For example, the query 
**
**   SELECT DISTINCT a, b, c FROM tbl WHERE a = ?
**
** can benefit from any index on columns "b" and "c".
*/
static int isDistinctIndex(
  Parse *pParse,                  /* Parsing context */
  WhereClause *pWC,               /* The WHERE clause */
  Index *pIdx,                    /* The index being considered */
  int base,                       /* Cursor number for the table pIdx is on */
  ExprList *pDistinct,            /* The DISTINCT expressions */
  int nEqCol                      /* Number of index columns with == */
){
  Bitmask mask = 0;               /* Mask of unaccounted for pDistinct exprs */
  int i;                          /* Iterator variable */

  if( pIdx->zName==0 || pDistinct==0 || pDistinct->nExpr>=BMS ) return 0;
  testcase( pDistinct->nExpr==BMS-1 );

  /* Loop through all the expressions in the distinct list. If any of them
  ** are not simple column references, return early. Otherwise, test if the
  ** WHERE clause contains a "col=X" clause. If it does, the expression
  ** can be ignored. If it does not, and the column does not belong to the
  ** same table as index pIdx, return early. Finally, if there is no
  ** matching "col=X" expression and the column is on the same table as pIdx,
  ** set the corresponding bit in variable mask.
  */
  for(i=0; i<pDistinct->nExpr; i++){
    WhereTerm *pTerm;
    Expr *p = pDistinct->a[i].pExpr;
    if( p->op!=TK_COLUMN ) return 0;
    pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
    if( pTerm ){
      Expr *pX = pTerm->pExpr;
      CollSeq *p1 = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
      CollSeq *p2 = sqlite4ExprCollSeq(pParse, p);
      if( p1==p2 ) continue;
    }
    if( p->iTable!=base ) return 0;
    mask |= (((Bitmask)1) << i);
  }

  for(i=nEqCol; mask && i<pIdx->nColumn; i++){
    int iExpr = findIndexCol(pParse, pDistinct, base, pIdx, i);
    if( iExpr<0 ) break;
    mask &= ~(((Bitmask)1) << iExpr);
  }

  return (mask==0);
}


/*
** Return true if the DISTINCT expression-list passed as the third argument
** is redundant. A DISTINCT list is redundant if the database contains a
** UNIQUE index that guarantees that the result of the query will be distinct
** anyway.
*/
static int isDistinctRedundant(
  Parse *pParse,
  SrcList *pTabList,
  WhereClause *pWC,
  ExprList *pDistinct
){
  Table *pTab;
  Index *pIdx;
  int i;                          
  int iBase;

  /* If there is more than one table or sub-select in the FROM clause of
  ** this query, then it will not be possible to show that the DISTINCT 
  ** clause is redundant. */
  if( pTabList->nSrc!=1 ) return 0;
  iBase = pTabList->a[0].iCursor;
  pTab = pTabList->a[0].pTab;

  /* If any of the expressions is an IPK column on table iBase, then return 
  ** true. Note: The (p->iTable==iBase) part of this test may be false if the
  ** current SELECT is a correlated sub-query.
  */
  for(i=0; i<pDistinct->nExpr; i++){
    Expr *p = pDistinct->a[i].pExpr;
    if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
  }

  /* Loop through all indices on the table, checking each to see if it makes
  ** the DISTINCT qualifier redundant. It does so if:
  **
  **   1. The index is itself UNIQUE, and
  **
  **   2. All of the columns in the index are either part of the pDistinct
  **      list, or else the WHERE clause contains a term of the form "col=X",
  **      where X is a constant value. The collation sequences of the
  **      comparison and select-list expressions must match those of the index.



  */
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    if( pIdx->onError==OE_None ) continue;
    for(i=0; i<pIdx->nColumn; i++){
      int iCol = pIdx->aiColumn[i];
      if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) 
       && 0>findIndexCol(pParse, pDistinct, iBase, pIdx, i)
      ){
        break;

      }
    }
    if( i==pIdx->nColumn ){
      /* This index implies that the DISTINCT qualifier is redundant. */
      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( pPk && iIdxCol<(pIdx->nColumn + pPk->nColumn) ){
    iRet = pPk->aiColumn[iIdxCol - pIdx->nColumn];
  }
  return iRet;
}

/*
** Return the name of the iCol'th column of table pTab. Or, if iCol is less
** than zero, return a pointer to the constant string "rowid".
*/
static const char *tblColumnName(Table *pTab, int iCol){
  if( iCol<0 ) return "rowid";
  return pTab->aCol[iCol].zName;
}

/*
** 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
** the table has a cursor number of "base".  pIdx is an index on pTab.
**
** nEqCol is the number of columns of pIdx that are used as equality
** constraints.  Any of these columns may be missing from the ORDER BY
** clause and the match can still be a success.
**
** All terms of the ORDER BY that match against the index must be either
** ASC or DESC.  (Terms of the ORDER BY clause past the end of a UNIQUE
** index do not need to satisfy this constraint.)  The *pbRev value is
** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
** the ORDER BY clause is all ASC.
*/
static int isSortingIndex(
  Parse *pParse,          /* Parsing context */
  WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */
  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->fIndex & IDX_Unordered ) 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++){
    ExprListItem *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 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 if( iColumn>=0 ) {

      zColl = pTab->aCol[iColumn].zColl;
    }else{
      zColl = 0;
    }
    if( pColl!=sqlite4FindCollSeq(db, zColl, 0) ) break;

    if( iIdxCol==iNext ){
      u8 reqSortOrder;
      u8 idxSortOrder = SQLITE4_SO_ASC;
      if( iIdxCol<pIdx->nColumn ) idxSortOrder = pIdx->aSortOrder[iIdxCol];
      assert( idxSortOrder==SQLITE4_SO_ASC || idxSortOrder==SQLITE4_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)
** complexity.  Because N is just a guess, it is no great tragedy if
** logN is a little off.
*/
static double estLog(double N){
  double logN = 1;
  double x = 10;
  while( N>x ){
    logN += 1;
    x *= 10;
  }
  return logN;
}

/*
** Two routines for printing the content of an sqlite4_index_info
** structure.  Used for testing and debugging only.  If neither
** SQLITE4_TEST or SQLITE4_DEBUG are defined, then these routines
** are no-ops.
*/
#if !defined(SQLITE4_OMIT_VIRTUALTABLE) && defined(SQLITE4_DEBUG)
static void TRACE_IDX_INPUTS(sqlite4_index_info *p){
  int i;
  if( !sqlite4WhereTrace ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite4DebugPrintf("  constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
       i,
       p->aConstraint[i].iColumn,
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
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
2321
2322
2323
2324
2325
2326
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
2398
2399
2400
2401

2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
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
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472

2473
2474
2475
2476
2477
2478
2479
  sqlite4DebugPrintf("  orderByConsumed=%d\n", p->orderByConsumed);
  sqlite4DebugPrintf("  estimatedCost=%g\n", p->estimatedCost);
}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif








































































































#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
** could be used with an index to access pSrc, assuming an appropriate
** index existed.
*/
static int termCanDriveIndex(
  WhereTerm *pTerm,              /* WHERE clause term to check */
  struct SrcListItem *pSrc,     /* Table we are trying to access */
  Bitmask notReady               /* Tables in outer loops of the join */
){
  char aff;
  if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
  if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
  if( (pTerm->prereqRight & notReady)!=0 ) return 0;
  if( pTerm->u.leftColumn<0 ) return 0;
  aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
  if( !sqlite4IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
  return 1;
}
#endif















































































#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
/*
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
** makes use of the automatic index.
*/
static void constructAutomaticIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcListItem *pSrc,  /* The FROM clause term to get the next index */
  Bitmask notReady,           /* Mask of cursors that are not available */
  WhereLevel *pLevel          /* Write new index here */
){
  int nColumn;                /* Number of columns in the constructed index */
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  WhereTerm *pWCEnd;          /* End of pWC->a[] */
  int nByte;                  /* Byte of memory needed for pIdx */
  Index *pIdx;                /* Object describing the transient index */
  Vdbe *v;                    /* Prepared statement under construction */
  int addrInit;               /* Address of the initialization bypass jump */
  Table *pTable;              /* The table being indexed */
  KeyInfo *pKeyinfo;          /* Key information for the index */   
  int addrTop;                /* Top of the index fill loop */
  int regRecord;              /* Register holding an index value */
  int regKey;                 /* Register holding an index key */
  int n;                      /* Column counter */
  int i;                      /* Loop counter */
  int mxBitCol;               /* Maximum column in pSrc->colUsed */
  int iPkCsr;                 /* PK cursor number */
  CollSeq *pColl;             /* Collating sequence to on a column */
  WhereLoop *pLoop;           /* The Loop object */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
  u8 sentWarning = 0;         /* True if a warnning has been issued */


  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
  v = pParse->pVdbe;
  assert( v!=0 );
  addrInit = sqlite4CodeOnce(pParse);

  /* Count the number of columns that will be added to the index
  ** and used to match WHERE clause constraints */
  nColumn = 0;
  pTable = pSrc->pTab;
  pWCEnd = &pWC->a[pWC->nTerm];
  pLoop = pLevel->pWLoop;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );
      if( !sentWarning ){
        sqlite4_log(pParse->db->pEnv, SQLITE4_WARNING_AUTOINDEX,
            "automatic index on %s(%s)", pTable->zName,
            pTable->aCol[iCol].zName);
        sentWarning = 1;
      }
      if( (idxCols & cMask)==0 ){
        if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return;
        pLoop->aLTerm[nColumn++] = pTerm;
        idxCols |= cMask;
      }
    }
  }
  assert( nColumn>0 );
  pLoop->u.btree.nEq = pLoop->nLTerm = nColumn;
  pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
                     | WHERE_AUTO_INDEX;

  /* Count the number of additional columns needed to create a
  ** covering index.  A "covering index" is an index that contains all
  ** columns that are needed by the query.  With a covering index, the
  ** original table never needs to be accessed.  Automatic indices must
  ** be a covering index because the index will not be updated if the
  ** original table changes and the index and table cannot both be used
  ** if they go out of sync.
  */
  extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
  mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
  testcase( pTable->nCol==BMS-1 );
  testcase( pTable->nCol==BMS-2 );
  for(i=0; i<mxBitCol; i++){
    if( extraCols & MASKBIT(i) ) nColumn++;
  }
  if( pSrc->colUsed & MASKBIT(BMS-1) ){
    nColumn += pTable->nCol - BMS + 1;
  }
  pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;

  /* Construct the Index object to describe this index */
  nByte = sizeof(Index);
  nByte += nColumn*sizeof(int);     /* Index.aiColumn */
  nByte += nColumn*sizeof(char*);   /* Index.azColl */
  nByte += nColumn;                 /* Index.aSortOrder */
  pIdx = sqlite4DbMallocZero(pParse->db, nByte);
  if( pIdx==0 ) return;
  pLoop->u.btree.pIndex = pIdx;

  pIdx->azColl = (char**)&pIdx[1];
  pIdx->aiColumn = (int*)&pIdx->azColl[nColumn];
  pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
  pIdx->zName = "auto-index";
  pIdx->nColumn = nColumn;
  pIdx->pTable = pTable;
  pIdx->aiCover = pIdx->aiColumn;
  pIdx->nCover = pIdx->nColumn;
  pIdx->eIndexType = SQLITE4_INDEX_TEMP;
  n = 0;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
      testcase( iCol==BMS-1 );
      testcase( iCol==BMS );
      if( (idxCols & cMask)==0 ){
        Expr *pX = pTerm->pExpr;
        idxCols |= cMask;
        pIdx->aiColumn[n] = pTerm->u.leftColumn;
        pColl = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
        pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
        n++;
      }
    }
  }
  assert( (u32)n==pLoop->u.btree.nEq );

  /* Add additional columns needed to make the automatic index into
  ** a covering index */
  for(i=0; i<mxBitCol; i++){
    if( extraCols & MASKBIT(i) ){
      pIdx->aiColumn[n] = i;
      pIdx->azColl[n] = "BINARY";
      n++;
    }
  }
  if( pSrc->colUsed & MASKBIT(BMS-1) ){
    for(i=BMS-1; i<pTable->nCol; i++){
      pIdx->aiColumn[n] = i;
      pIdx->azColl[n] = "BINARY";
      n++;
    }
  }
  assert( n==nColumn );

  /* Create the automatic index */
  pKeyinfo = sqlite4IndexKeyinfo(pParse, pIdx);
  assert( pLevel->iIdxCur>=0 );
  pLevel->iIdxCur = pParse->nTab++;
  sqlite4VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
                    (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */
  iPkCsr = pLevel->iTabCur;
  addrTop = sqlite4VdbeAddOp1(v, OP_Rewind, iPkCsr);
  regRecord = sqlite4GetTempRange(pParse, 2);
  regKey = regRecord + 1;

  sqlite4EncodeIndexKey(pParse, 0, iPkCsr, pIdx, pLevel->iIdxCur, 1, regKey);
  sqlite4EncodeIndexValue(pParse, iPkCsr, pIdx, regRecord);
  sqlite4VdbeAddOp3(v, OP_Insert, pLevel->iIdxCur, regRecord, regKey);
  /* sqlite4VdbeChangeP5(v, OPFLAG_USESEEKRESULT); */
  sqlite4VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
  sqlite4VdbeChangeP5(v, SQLITE4_STMTSTATUS_AUTOINDEX);
  sqlite4VdbeJumpHere(v, addrTop);
  sqlite4ReleaseTempRange(pParse, regRecord, 2);
  
  /* Jump here when skipping the initialization */
  sqlite4VdbeJumpHere(v, addrInit);
}
#endif /* SQLITE4_OMIT_AUTOMATIC_INDEX */

#ifndef SQLITE4_OMIT_VIRTUALTABLE
/*
** Allocate and populate an sqlite4_index_info structure. It is the 
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite4_free().
*/
static sqlite4_index_info *allocateIndexInfo(
  Parse *pParse,
  WhereClause *pWC,
  struct SrcListItem *pSrc,
  ExprList *pOrderBy
){
  int i, j;
  int nTerm;
  struct sqlite4_index_constraint *pIdxCons;
  struct sqlite4_index_orderby *pIdxOrderBy;
  struct sqlite4_index_constraint_usage *pUsage;
  WhereTerm *pTerm;
  int nOrderBy;
  sqlite4_index_info *pIdxInfo;



  /* Count the number of possible WHERE clause constraints referring
  ** to this virtual table */
  for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    if( pTerm->leftCursor != pSrc->iCursor ) continue;
    assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
    testcase( pTerm->eOperator & WO_IN );
    testcase( pTerm->eOperator & WO_ISNULL );
    if( pTerm->eOperator & (WO_ISNULL) ) continue;
    if( pTerm->wtFlags & TERM_VNULL ) continue;
    nTerm++;
  }

  /* If the ORDER BY clause contains only columns in the current 
  ** virtual table then allocate space for the aOrderBy part of
  ** the sqlite4_index_info structure.
  */
  nOrderBy = 0;
  if( pOrderBy ){
    int n = pOrderBy->nExpr;
    for(i=0; i<n; i++){
      Expr *pExpr = pOrderBy->a[i].pExpr;
      if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
    }
    if( i==n){
      nOrderBy = n;
    }
  }

  /* Allocate the sqlite4_index_info structure
  */
  pIdxInfo = sqlite4DbMallocZero(pParse->db, sizeof(*pIdxInfo)
                           + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
                           + sizeof(*pIdxOrderBy)*nOrderBy );
  if( pIdxInfo==0 ){
    sqlite4ErrorMsg(pParse, "out of memory");

    return 0;
  }

  /* Initialize the structure.  The sqlite4_index_info structure contains
  ** many fields that are declared "const" to prevent xBestIndex from
  ** changing them.  We have to do some funky casting in order to
  ** initialize those fields.
  */
  pIdxCons = (struct sqlite4_index_constraint*)&pIdxInfo[1];
  pIdxOrderBy = (struct sqlite4_index_orderby*)&pIdxCons[nTerm];
  pUsage = (struct sqlite4_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
  *(int*)&pIdxInfo->nConstraint = nTerm;
  *(int*)&pIdxInfo->nOrderBy = nOrderBy;
  *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;
  *(struct sqlite4_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
  *(struct sqlite4_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
                                                                   pUsage;

  for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    u8 op;
    if( pTerm->leftCursor != pSrc->iCursor ) continue;
    assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
    testcase( pTerm->eOperator & WO_IN );
    testcase( pTerm->eOperator & WO_ISNULL );
    if( pTerm->eOperator & (WO_ISNULL) ) continue;
    if( pTerm->wtFlags & TERM_VNULL ) continue;
    pIdxCons[j].iColumn = pTerm->u.leftColumn;
    pIdxCons[j].iTermOffset = i;
    op = (u8)pTerm->eOperator & WO_ALL;
    if( op==WO_IN ) op = WO_EQ;
    pIdxCons[j].op = op;
    /* The direct assignment in the previous line is possible only because
    ** the WO_ and SQLITE4_INDEX_CONSTRAINT_ codes are identical.  The
    ** following asserts verify this fact. */
    assert( WO_EQ==SQLITE4_INDEX_CONSTRAINT_EQ );
    assert( WO_LT==SQLITE4_INDEX_CONSTRAINT_LT );
    assert( WO_LE==SQLITE4_INDEX_CONSTRAINT_LE );
    assert( WO_GT==SQLITE4_INDEX_CONSTRAINT_GT );
    assert( WO_GE==SQLITE4_INDEX_CONSTRAINT_GE );
    assert( WO_MATCH==SQLITE4_INDEX_CONSTRAINT_MATCH );
    assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
    j++;
  }
  for(i=0; i<nOrderBy; i++){
    Expr *pExpr = pOrderBy->a[i].pExpr;
    pIdxOrderBy[i].iColumn = pExpr->iColumn;
    pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
  }

  return pIdxInfo;
}

/*
** The table object reference passed as the second argument to this function
** must represent a virtual table. This function invokes the xBestIndex()
** method of the virtual table with the sqlite4_index_info object that
** comes in as the 3rd argument to this function.
**
** If an error occurs, pParse is populated with an error message and a
** non-zero value is returned. Otherwise, 0 is returned and the output
** part of the sqlite4_index_info structure is left populated.
**
** Whether or not an error is returned, it is the responsibility of the
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite4_index_info *p){
  sqlite4_vtab *pVtab = sqlite4GetVTable(pParse->db, pTab)->pVtab;
  int i;
  int rc;


  TRACE_IDX_INPUTS(p);
  rc = pVtab->pModule->xBestIndex(pVtab, p);
  TRACE_IDX_OUTPUTS(p);

  if( rc!=SQLITE4_OK ){
    if( rc==SQLITE4_NOMEM ){
      pParse->db->mallocFailed = 1;








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








|




|

<






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










|



|





|


|
|


<
<
<

<

<
<
>





|

|
|
|


<




|


<
<
<
<
<
<

<
|




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


|
|
|
|


|
>

|
|

|

<
<
<





|
<
<










|

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


<
|
|


|
<
<

|
>
|
|
|
<
|

|



|










|

|











>
>




|
|
|
|










<
|



|
|










>



















<

|
|
|
|



<
<
|









|














|
|














>







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
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
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
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076



2077

2078


2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091

2092
2093
2094
2095
2096
2097
2098






2099

2100
2101
2102
2103
2104
2105



2106


















2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
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
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
  sqlite4DebugPrintf("  orderByConsumed=%d\n", p->orderByConsumed);
  sqlite4DebugPrintf("  estimatedCost=%g\n", p->estimatedCost);
}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif

/* 
** Required because bestIndex() is called by bestOrClauseIndex() 
*/
static void bestIndex(
    Parse*, WhereClause*, SrcListItem*,
    Bitmask, Bitmask, ExprList*, WhereCost*);

/*
** This routine attempts to find an scanning strategy that can be used 
** to optimize an 'OR' expression that is part of a WHERE clause. 
**
** The table associated with FROM clause term pSrc may be either a
** regular B-Tree table or a virtual table.
*/
static void bestOrClauseIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  SrcListItem *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors not available for indexing */
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  WhereCost *pCost            /* Lowest cost query plan */
){
#ifndef SQLITE4_OMIT_OR_OPTIMIZATION
  const int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur);  /* Bitmask for pSrc */
  WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm];        /* End of pWC->a[] */
  WhereTerm *pTerm;                 /* A single term of the WHERE clause */

  /* The OR-clause optimization is disallowed if the INDEXED BY or
  ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
  if( pSrc->notIndexed || pSrc->pIndex!=0 ){
    return;
  }
  if( pWC->wctrlFlags & WHERE_AND_ONLY ){
    return;
  }

  /* Search the WHERE clause terms for a usable WO_OR term. */
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( pTerm->eOperator==WO_OR 
     && ((pTerm->prereqAll & ~maskSrc) & notReady)==0
     && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
      WhereTerm *pOrTerm;
      int flags = WHERE_MULTI_OR;
      double rTotal = 0;
      double nRow = 0;
      Bitmask used = 0;

      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        WhereCost sTermCost;
        WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 
          (pOrTerm - pOrWC->a), (pTerm - pWC->a)
        ));
        if( pOrTerm->eOperator==WO_AND ){
          WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
          bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
        }else if( pOrTerm->leftCursor==iCur ){
          WhereClause tempWC;
          tempWC.pParse = pWC->pParse;
          tempWC.pMaskSet = pWC->pMaskSet;
          tempWC.pOuter = pWC;
          tempWC.op = TK_AND;
          tempWC.a = pOrTerm;
          tempWC.wctrlFlags = 0;
          tempWC.nTerm = 1;
          bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
        }else{
          continue;
        }
        rTotal += sTermCost.rCost;
        nRow += sTermCost.plan.nRow;
        used |= sTermCost.used;
        if( rTotal>=pCost->rCost ) break;
      }

      /* If there is an ORDER BY clause, increase the scan cost to account 
      ** for the cost of the sort. */
      if( pOrderBy!=0 ){
        WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
                    rTotal, rTotal+nRow*estLog(nRow)));
        rTotal += nRow*estLog(nRow);
      }

      /* If the cost of scanning using this OR term for optimization is
      ** less than the current cost stored in pCost, replace the contents
      ** of pCost. */
      WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
      if( rTotal<pCost->rCost ){
        pCost->rCost = rTotal;
        pCost->used = used;
        pCost->plan.nRow = nRow;
        pCost->plan.wsFlags = flags;
        pCost->plan.u.pTerm = pTerm;
      }
    }
  }
#endif /* SQLITE4_OMIT_OR_OPTIMIZATION */
}

#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
** could be used with an index to access pSrc, assuming an appropriate
** index existed.
*/
static int termCanDriveIndex(
  WhereTerm *pTerm,              /* WHERE clause term to check */
  SrcListItem *pSrc,     /* Table we are trying to access */
  Bitmask notReady               /* Tables in outer loops of the join */
){
  char aff;
  if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
  if( pTerm->eOperator!=WO_EQ ) return 0;
  if( (pTerm->prereqRight & notReady)!=0 ) return 0;

  aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
  if( !sqlite4IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
  return 1;
}
#endif

#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
/*
** If the query plan for pSrc specified in pCost is a full table scan
** and indexing is allows (if there is no NOT INDEXED clause) and it
** possible to construct a transient index that would perform better
** than a full table scan even when the cost of constructing the index
** is taken into account, then alter the query plan to use the
** transient index.
*/
static void bestAutomaticIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  SrcListItem *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors that are not available */
  WhereCost *pCost            /* Lowest cost query plan */
){
  double nTableRow;           /* Rows in the input table */
  double logN;                /* log(nTableRow) */
  double costTempIdx;         /* per-query cost of the transient index */
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  WhereTerm *pWCEnd;          /* End of pWC->a[] */
  Table *pTable;              /* Table tht might be indexed */

  if( pParse->nQueryLoop<=(double)1 ){
    /* There is no point in building an automatic index for a single scan */
    return;
  }
  if( (pParse->db->flags & SQLITE4_AutoIndex)==0 ){
    /* Automatic indices are disabled at run-time */
    return;
  }
  if( (pWC->wctrlFlags & WHERE_NO_AUTOINDEX)!=0 ){
    return;
  }
  if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
    /* We already have some kind of index in use for this query. */
    return;
  }
  if( pSrc->notIndexed ){
    /* The NOT INDEXED clause appears in the SQL. */
    return;
  }
  if( pSrc->isCorrelated ){
    /* The source is a correlated sub-query. No point in indexing it. */
    return;
  }

  assert( pParse->nQueryLoop >= (double)1 );
  pTable = pSrc->pTab;
  nTableRow = pTable->nRowEst;
  logN = estLog(nTableRow);
  costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
  if( costTempIdx>=pCost->rCost ){
    /* The cost of creating the transient table would be greater than
    ** doing the full table scan */
    return;
  }

  /* Search for any equality comparison term */
  pWCEnd = &pWC->a[pWC->nTerm];
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
                    pCost->rCost, costTempIdx));
      pCost->rCost = costTempIdx;
      pCost->plan.nRow = logN + 1;
      pCost->plan.wsFlags = WHERE_TEMP_INDEX;
      pCost->plan.u.pIdx = 0;
      pCost->used = pTerm->prereqRight;
      break;
    }
  }
}
#else
# define bestAutomaticIndex(A,B,C,D,E)  /* no-op */
#endif /* SQLITE4_OMIT_AUTOMATIC_INDEX */


#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
/*
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
** makes use of the automatic index.
*/
static void constructAutomaticIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  SrcListItem *pSrc,  /* The FROM clause term to get the next index */
  Bitmask notReady,           /* Mask of cursors that are not available */
  WhereLevel *pLevel          /* Write new index here */
){
  int nCol = 0;               /* Number of columns in index keys */
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  WhereTerm *pWCEnd;          /* End of pWC->a[] */
  int nByte;                  /* Byte of memory needed for pIdx */
  Index *pIdx;                /* Object describing the transient index */
  Vdbe *v;                    /* Prepared statement under construction */
  int addrOnce;               /* Address of the initialization bypass jump */
  Table *pTable;              /* The table being indexed */
  KeyInfo *pKeyinfo;          /* Key information for the index */   
  int addrRewind;             /* Top of the index fill loop */
  int regRecord;              /* Register holding an index record */
  int regKey;                 /* Register holding an index key */
  int n;                      /* Column counter */



  CollSeq *pColl;             /* Collating sequence to on a column */

  Bitmask idxCols;            /* Bitmap of columns used for indexing */


  int iPkCur = pLevel->iTabCur;   /* Primary key cursor to read data from */

  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
  v = pParse->pVdbe;
  assert( v!=0 );
  addrOnce = sqlite4CodeOnce(pParse);

  /* Count the number of columns that will be encoded into the index keys.
  ** set nCol to this value. Use the idxCols mask to ensure that the same
  ** column is not added to the index more than once.  */
  pTable = pSrc->pTab;
  pWCEnd = &pWC->a[pWC->nTerm];

  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
      testcase( iCol==BMS );
      testcase( iCol==BMS-1 );






      if( (idxCols & cMask)==0 ){

        nCol++;
        idxCols |= cMask;
      }
    }
  }
  assert( nCol>0 );



  pLevel->plan.nEq = nCol;


















  pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ;

  /* Construct the Index object to describe this index */
  nByte = sizeof(Index);          /* Index */
  nByte += nCol*sizeof(int);      /* Index.aiColumn */
  nByte += nCol*sizeof(char*);    /* Index.azColl */
  nByte += nCol;                  /* Index.aSortOrder */
  pIdx = sqlite4DbMallocZero(pParse->db, nByte);
  if( pIdx==0 ) return;
  pLevel->plan.u.pIdx = pIdx;
  pIdx->eIndexType = SQLITE4_INDEX_TEMP;
  pIdx->azColl = (char**)&pIdx[1];
  pIdx->aiColumn = (int*)&pIdx->azColl[nCol];
  pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nCol];
  pIdx->zName = "auto-index";
  pIdx->nColumn = nCol;
  pIdx->pTable = pTable;



  n = 0;
  idxCols = 0;
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
      int iCol = pTerm->u.leftColumn;
      Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;


      if( (idxCols & cMask)==0 ){
        Expr *pX = pTerm->pExpr;
        idxCols |= cMask;
        pIdx->aiColumn[n] = pTerm->u.leftColumn;
        pColl = sqlite4BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
        pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
        n++;
      }
    }
  }
  assert( (u32)n==pLevel->plan.nEq );



















  /* Open the automatic index cursor */
  pKeyinfo = sqlite4IndexKeyinfo(pParse, pIdx);
  assert( pLevel->iIdxCur>=0 );

  sqlite4VdbeAddOp3(v, OP_OpenAutoindex, pLevel->iIdxCur, 0, 0);
  sqlite4VdbeChangeP4(v, -1, (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
  VdbeComment((v, "for %s", pTable->zName));

  /* Populate the automatic index */


  regRecord = sqlite4GetTempRange(pParse, 2);
  regKey = regRecord+1;
  addrRewind = sqlite4VdbeAddOp1(v, OP_Rewind, iPkCur);
  sqlite4EncodeIndexKey(pParse, 0, iPkCur, pIdx, pLevel->iIdxCur, 1, regKey);
  sqlite4VdbeAddOp2(v, OP_RowData, iPkCur, regRecord);
  sqlite4VdbeAddOp3(v, OP_IdxInsert, pLevel->iIdxCur, regRecord, regKey);

  sqlite4VdbeAddOp2(v, OP_Next, iPkCur, addrRewind+1);
  sqlite4VdbeChangeP5(v, SQLITE4_STMTSTATUS_AUTOINDEX);
  sqlite4VdbeJumpHere(v, addrRewind);
  sqlite4ReleaseTempRange(pParse, regRecord, 2);
  
  /* Jump here when skipping the initialization */
  sqlite4VdbeJumpHere(v, addrOnce);
}
#endif /* SQLITE4_OMIT_AUTOMATIC_INDEX */

#ifndef SQLITE4_OMIT_VIRTUALTABLE
/*
** Allocate and populate an sqlite4_index_info structure. It is the 
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite4_free().
*/
static sqlite4_index_info *allocateIndexInfo(
  Parse *pParse, 
  WhereClause *pWC,
  SrcListItem *pSrc,
  ExprList *pOrderBy
){
  int i, j;
  int nTerm;
  struct sqlite4_index_constraint *pIdxCons;
  struct sqlite4_index_orderby *pIdxOrderBy;
  struct sqlite4_index_constraint_usage *pUsage;
  WhereTerm *pTerm;
  int nOrderBy;
  sqlite4_index_info *pIdxInfo;

  WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));

  /* Count the number of possible WHERE clause constraints referring
  ** to this virtual table */
  for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    if( pTerm->leftCursor != pSrc->iCursor ) continue;
    assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
    testcase( pTerm->eOperator==WO_IN );
    testcase( pTerm->eOperator==WO_ISNULL );
    if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
    if( pTerm->wtFlags & TERM_VNULL ) continue;
    nTerm++;
  }

  /* If the ORDER BY clause contains only columns in the current 
  ** virtual table then allocate space for the aOrderBy part of
  ** the sqlite4_index_info structure.
  */
  nOrderBy = 0;
  if( pOrderBy ){

    for(i=0; i<pOrderBy->nExpr; i++){
      Expr *pExpr = pOrderBy->a[i].pExpr;
      if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
    }
    if( i==pOrderBy->nExpr ){
      nOrderBy = pOrderBy->nExpr;
    }
  }

  /* Allocate the sqlite4_index_info structure
  */
  pIdxInfo = sqlite4DbMallocZero(pParse->db, sizeof(*pIdxInfo)
                           + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
                           + sizeof(*pIdxOrderBy)*nOrderBy );
  if( pIdxInfo==0 ){
    sqlite4ErrorMsg(pParse, "out of memory");
    /* (double)0 In case of SQLITE4_OMIT_FLOATING_POINT... */
    return 0;
  }

  /* Initialize the structure.  The sqlite4_index_info structure contains
  ** many fields that are declared "const" to prevent xBestIndex from
  ** changing them.  We have to do some funky casting in order to
  ** initialize those fields.
  */
  pIdxCons = (struct sqlite4_index_constraint*)&pIdxInfo[1];
  pIdxOrderBy = (struct sqlite4_index_orderby*)&pIdxCons[nTerm];
  pUsage = (struct sqlite4_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
  *(int*)&pIdxInfo->nConstraint = nTerm;
  *(int*)&pIdxInfo->nOrderBy = nOrderBy;
  *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;
  *(struct sqlite4_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
  *(struct sqlite4_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
                                                                   pUsage;

  for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){

    if( pTerm->leftCursor != pSrc->iCursor ) continue;
    assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
    testcase( pTerm->eOperator==WO_IN );
    testcase( pTerm->eOperator==WO_ISNULL );
    if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
    if( pTerm->wtFlags & TERM_VNULL ) continue;
    pIdxCons[j].iColumn = pTerm->u.leftColumn;
    pIdxCons[j].iTermOffset = i;


    pIdxCons[j].op = (u8)pTerm->eOperator;
    /* The direct assignment in the previous line is possible only because
    ** the WO_ and SQLITE4_INDEX_CONSTRAINT_ codes are identical.  The
    ** following asserts verify this fact. */
    assert( WO_EQ==SQLITE4_INDEX_CONSTRAINT_EQ );
    assert( WO_LT==SQLITE4_INDEX_CONSTRAINT_LT );
    assert( WO_LE==SQLITE4_INDEX_CONSTRAINT_LE );
    assert( WO_GT==SQLITE4_INDEX_CONSTRAINT_GT );
    assert( WO_GE==SQLITE4_INDEX_CONSTRAINT_GE );
    assert( WO_MATCH==SQLITE4_INDEX_CONSTRAINT_MATCH );
    assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
    j++;
  }
  for(i=0; i<nOrderBy; i++){
    Expr *pExpr = pOrderBy->a[i].pExpr;
    pIdxOrderBy[i].iColumn = pExpr->iColumn;
    pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
  }

  return pIdxInfo;
}

/*
** The table object reference passed as the second argument to this function
** must represent a virtual table. This function invokes the xBestIndex()
** method of the virtual table with the sqlite4_index_info pointer passed
** as the argument.
**
** If an error occurs, pParse is populated with an error message and a
** non-zero value is returned. Otherwise, 0 is returned and the output
** part of the sqlite4_index_info structure is left populated.
**
** Whether or not an error is returned, it is the responsibility of the
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite4_index_info *p){
  sqlite4_vtab *pVtab = sqlite4GetVTable(pParse->db, pTab)->pVtab;
  int i;
  int rc;

  WHERETRACE(("xBestIndex for %s\n", pTab->zName));
  TRACE_IDX_INPUTS(p);
  rc = pVtab->pModule->xBestIndex(pVtab, p);
  TRACE_IDX_OUTPUTS(p);

  if( rc!=SQLITE4_OK ){
    if( rc==SQLITE4_NOMEM ){
      pParse->db->mallocFailed = 1;
2491
2492
2493
2494
2495
2496
2497
2498
2499


































2500
























































































































2501
2502
2503
2504
2505
2506
2507
      sqlite4ErrorMsg(pParse, 
          "table %s: xBestIndex returned an invalid plan", pTab->zName);
    }
  }

  return pParse->nErr;
}
#endif /* !defined(SQLITE4_OMIT_VIRTUALTABLE) */




























































































































































#ifdef SQLITE4_ENABLE_STAT3
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pVal
**    aStat[1]      Est. number of rows equal to pVal







|

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

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







2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
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
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
      sqlite4ErrorMsg(pParse, 
          "table %s: xBestIndex returned an invalid plan", pTab->zName);
    }
  }

  return pParse->nErr;
}


/*
** Compute the best index for a virtual table.
**
** The best index is computed by the xBestIndex method of the virtual
** table module.  This routine is really just a wrapper that sets up
** the sqlite4_index_info structure that is used to communicate with
** xBestIndex.
**
** In a join, this routine might be called multiple times for the
** same virtual table.  The sqlite4_index_info structure is created
** and initialized on the first invocation and reused on all subsequent
** invocations.  The sqlite4_index_info structure is also used when
** code is generated to access the virtual table.  The whereInfoDelete() 
** routine takes care of freeing the sqlite4_index_info structure after
** everybody has finished with it.
*/
static void bestVirtualIndex(
  Parse *pParse,                  /* The parsing context */
  WhereClause *pWC,               /* The WHERE clause */
  SrcListItem *pSrc,      /* The FROM clause term to search */
  Bitmask notReady,               /* Mask of cursors not available for index */
  Bitmask notValid,               /* Cursors not valid for any purpose */
  ExprList *pOrderBy,             /* The order by clause */
  WhereCost *pCost,               /* Lowest cost query plan */
  sqlite4_index_info **ppIdxInfo  /* Index information passed to xBestIndex */
){
  Table *pTab = pSrc->pTab;
  sqlite4_index_info *pIdxInfo;
  struct sqlite4_index_constraint *pIdxCons;
  struct sqlite4_index_constraint_usage *pUsage;
  WhereTerm *pTerm;
  int i, j;
  int nOrderBy;
  double rCost;

  /* Make sure wsFlags is initialized to some sane value. Otherwise, if the 
  ** malloc in allocateIndexInfo() fails and this function returns leaving
  ** wsFlags in an uninitialized state, the caller may behave unpredictably.
  */
  memset(pCost, 0, sizeof(*pCost));
  pCost->plan.wsFlags = WHERE_VIRTUALTABLE;

  /* If the sqlite4_index_info structure has not been previously
  ** allocated and initialized, then allocate and initialize it now.
  */
  pIdxInfo = *ppIdxInfo;
  if( pIdxInfo==0 ){
    *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy);
  }
  if( pIdxInfo==0 ){
    return;
  }

  /* At this point, the sqlite4_index_info structure that pIdxInfo points
  ** to will have been initialized, either during the current invocation or
  ** during some prior invocation.  Now we just have to customize the
  ** details of pIdxInfo for the current invocation and pass it to
  ** xBestIndex.
  */

  /* The module name must be defined. Also, by this point there must
  ** be a pointer to an sqlite4_vtab structure. Otherwise
  ** sqlite4ViewGetColumnNames() would have picked up the error. 
  */
  assert( pTab->azModuleArg && pTab->azModuleArg[0] );
  assert( sqlite4GetVTable(pParse->db, pTab) );

  /* Set the aConstraint[].usable fields and initialize all 
  ** output variables to zero.
  **
  ** aConstraint[].usable is true for constraints where the right-hand
  ** side contains only references to tables to the left of the current
  ** table.  In other words, if the constraint is of the form:
  **
  **           column = expr
  **
  ** and we are evaluating a join, then the constraint on column is 
  ** only valid if all tables referenced in expr occur to the left
  ** of the table containing column.
  **
  ** The aConstraints[] array contains entries for all constraints
  ** on the current table.  That way we only have to compute it once
  ** even though we might try to pick the best index multiple times.
  ** For each attempt at picking an index, the order of tables in the
  ** join might be different so we have to recompute the usable flag
  ** each time.
  */
  pIdxCons = *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint;
  pUsage = pIdxInfo->aConstraintUsage;
  for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
    j = pIdxCons->iTermOffset;
    pTerm = &pWC->a[j];
    pIdxCons->usable = (pTerm->prereqRight&notReady) ? 0 : 1;
  }
  memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
  if( pIdxInfo->needToFreeIdxStr ){
    sqlite4_free(pIdxInfo->idxStr);
  }
  pIdxInfo->idxStr = 0;
  pIdxInfo->idxNum = 0;
  pIdxInfo->needToFreeIdxStr = 0;
  pIdxInfo->orderByConsumed = 0;
  /* ((double)2) In case of SQLITE4_OMIT_FLOATING_POINT... */
  pIdxInfo->estimatedCost = SQLITE4_BIG_DBL / ((double)2);
  nOrderBy = pIdxInfo->nOrderBy;
  if( !pOrderBy ){
    pIdxInfo->nOrderBy = 0;
  }

  if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
    return;
  }

  pIdxCons = *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++){
    if( pUsage[i].argvIndex>0 ){
      pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
    }
  }

  /* If there is an ORDER BY clause, and the selected virtual table index
  ** does not satisfy it, increase the cost of the scan accordingly. This
  ** matches the processing for non-virtual tables in bestKVIndex().
  */
  rCost = pIdxInfo->estimatedCost;
  if( pOrderBy && pIdxInfo->orderByConsumed==0 ){
    rCost += estLog(rCost)*rCost;
  }

  /* The cost is not allowed to be larger than SQLITE4_BIG_DBL (the
  ** inital value of lowestCost in this loop. If it is, then the
  ** (cost<lowestCost) test below will never be true.
  ** 
  ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT 
  ** is defined.
  */
  if( (SQLITE4_BIG_DBL/((double)2))<rCost ){
    pCost->rCost = (SQLITE4_BIG_DBL/((double)2));
  }else{
    pCost->rCost = rCost;
  }
  pCost->plan.u.pVtabIdx = pIdxInfo;
  if( pIdxInfo->orderByConsumed ){
    pCost->plan.wsFlags |= WHERE_ORDERBY;
  }
  pCost->plan.nEq = 0;
  pIdxInfo->nOrderBy = nOrderBy;

  /* Try to find a more efficient access pattern by using multiple indexes
  ** to optimize an OR expression within the WHERE clause. 
  */
  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
}
#endif /* SQLITE4_OMIT_VIRTUALTABLE */

#ifdef SQLITE4_ENABLE_STAT3
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pVal
**    aStat[1]      Est. number of rows equal to pVal
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639


2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
  }

  sqlite4ValueFree(pVal);
  return SQLITE4_OK;
}
#endif

/*
** TODO: Should this be ENABLE_STAT3 only.
** TODO: Comment this.
*/
static int whereSampleKeyinfo(Parse *pParse, Index *p, KeyInfo *pKeyInfo){
  CollSeq *pColl;
  memset(pKeyInfo, 0, sizeof(KeyInfo));


  pKeyInfo->nField = p->nColumn;
  pKeyInfo->nPK = 1;
  pKeyInfo->nData = 0;
  pKeyInfo->aSortOrder = p->aSortOrder;
  pKeyInfo->aColl[0] = pColl = sqlite4LocateCollSeq(pParse, p->azColl[0]);
  pKeyInfo->aColl[0] = pColl;
  return pColl ? SQLITE4_OK : SQLITE4_ERROR;
}


/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):







<
<
<
<



>
>








<







2600
2601
2602
2603
2604
2605
2606




2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619

2620
2621
2622
2623
2624
2625
2626
  }

  sqlite4ValueFree(pVal);
  return SQLITE4_OK;
}
#endif





static int whereSampleKeyinfo(Parse *pParse, Index *p, KeyInfo *pKeyInfo){
  CollSeq *pColl;
  memset(pKeyInfo, 0, sizeof(KeyInfo));
  pKeyInfo->db = pParse->db;
  pKeyInfo->enc = SQLITE4_UTF8;
  pKeyInfo->nField = p->nColumn;
  pKeyInfo->nPK = 1;
  pKeyInfo->nData = 0;
  pKeyInfo->aSortOrder = p->aSortOrder;
  pKeyInfo->aColl[0] = pColl = sqlite4LocateCollSeq(pParse, p->azColl[0]);
  pKeyInfo->aColl[0] = pColl;
  return pColl ? SQLITE4_OK : SQLITE4_ERROR;
}


/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
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
*/
static int whereRangeScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index containing the range-compared column; "x" */
  int nEq,             /* index into p->aCol[] of the range-compared column */
  WhereTerm *pLower,   /* Lower bound on the range. ex: "x>123" Might be NULL */
  WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */
){
  int rc = SQLITE4_OK;

#ifdef SQLITE4_ENABLE_STAT3

  if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE4_Stat3) ){
    sqlite4 *db = pParse->db;
    KeyInfo keyinfo;
    sqlite4_buffer buf;
    tRowcnt iLower = 0;
    tRowcnt iUpper = p->aiRowEst[0];
    tRowcnt a[2];
    u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;

    sqlite4_buffer_init(&buf, db->pEnv->pMM);
    rc = whereSampleKeyinfo(pParse, p, &keyinfo);

    if( rc==SQLITE4_OK && pLower ){
      Expr *pExpr = pLower->pExpr->pRight;
      rc = valueFromExpr(pParse, &keyinfo, pExpr, aff, &buf);
      assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
      if( rc==SQLITE4_OK && buf.n
       && whereKeyStats(pParse, p, &buf, 0, a)==SQLITE4_OK
      ){
        iLower = a[0];
        if( (pLower->eOperator & WO_GT)!=0 ) iLower += a[1];
      }
      sqlite4_buffer_set(&buf, 0, 0);
    }
    if( rc==SQLITE4_OK && pUpper ){
      Expr *pExpr = pUpper->pExpr->pRight;
      rc = valueFromExpr(pParse, &keyinfo, pExpr, aff, &buf);
      assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
      if( rc==SQLITE4_OK && buf.n
       && whereKeyStats(pParse, p, &buf, 1, a)==SQLITE4_OK
      ){
        iUpper = a[0];
        if( (pUpper->eOperator & WO_LE)!=0 ) iUpper += a[1];
      }
    }
    sqlite4_buffer_clear(&buf);
    if( rc==SQLITE4_OK ){
      WhereCost iBase = whereCost(p->aiRowEst[0]);
      if( iUpper>iLower ){


        iBase -= whereCost(iUpper - iLower);
      }
      *pRangeDiv = iBase;
      WHERETRACE(0x100, ("range scan regions: %u..%u  div=%d\n",
                         (u32)iLower, (u32)iUpper, *pRangeDiv));
      return SQLITE4_OK;
    }
  }
#else
  UNUSED_PARAMETER(pParse);
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(nEq);
#endif
  assert( pLower || pUpper );
  *pRangeDiv = 0;
  /* TUNING:  Each inequality constraint reduces the search space 4-fold.
  ** A BETWEEN operator, therefore, reduces the search space 16-fold */
  if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){
    *pRangeDiv += 20;  assert( 20==whereCost(4) );
  }
  if( pUpper ){
    *pRangeDiv += 20;  assert( 20==whereCost(4) );
  }
  return rc;
}

#ifdef SQLITE4_ENABLE_STAT3
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in







|





|


|











|




|






|




|




<
|
>
>
|

<
|
|









|
<
<
|
<
<
|
<
<







2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708

2709
2710
2711
2712
2713

2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725


2726


2727


2728
2729
2730
2731
2732
2733
2734
*/
static int whereRangeScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index containing the range-compared column; "x" */
  int nEq,             /* index into p->aCol[] of the range-compared column */
  WhereTerm *pLower,   /* Lower bound on the range. ex: "x>123" Might be NULL */
  WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  double *pRangeDiv   /* OUT: Reduce search space by this divisor */
){
  int rc = SQLITE4_OK;

#ifdef SQLITE4_ENABLE_STAT3

  if( nEq==0 && p->nSample ){
    sqlite4 *db = pParse->db;
    KeyInfo keyinfo;
    sqlite4_buffer buf;              /* Buffer used for index sample */
    tRowcnt iLower = 0;
    tRowcnt iUpper = p->aiRowEst[0];
    tRowcnt a[2];
    u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;

    sqlite4_buffer_init(&buf, db->pEnv->pMM);
    rc = whereSampleKeyinfo(pParse, p, &keyinfo);

    if( rc==SQLITE4_OK && pLower ){
      Expr *pExpr = pLower->pExpr->pRight;
      rc = valueFromExpr(pParse, &keyinfo, pExpr, aff, &buf);
      assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE );
      if( rc==SQLITE4_OK && buf.n
       && whereKeyStats(pParse, p, &buf, 0, a)==SQLITE4_OK
      ){
        iLower = a[0];
        if( pLower->eOperator==WO_GT ) iLower += a[1];
      }
      sqlite4_buffer_set(&buf, 0, 0);
    }
    if( rc==SQLITE4_OK && pUpper ){
      Expr *pExpr = pUpper->pExpr->pRight;
      rc = valueFromExpr(pParse, &keyinfo, pExpr, aff, &buf);
      assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE );
      if( rc==SQLITE4_OK && buf.n
       && whereKeyStats(pParse, p, &buf, 1, a)==SQLITE4_OK
      ){
        iUpper = a[0];
        if( pUpper->eOperator==WO_LE ) iUpper += a[1];
      }
    }
    sqlite4_buffer_clear(&buf);
    if( rc==SQLITE4_OK ){

      if( iUpper<=iLower ){
        *pRangeDiv = (double)p->aiRowEst[0];
      }else{
        *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
      }

      WHERETRACE(("range scan regions: %u..%u  div=%g\n",
                  (u32)iLower, (u32)iUpper, *pRangeDiv));
      return SQLITE4_OK;
    }
  }
#else
  UNUSED_PARAMETER(pParse);
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(nEq);
#endif
  assert( pLower || pUpper );
  *pRangeDiv = (double)1;


  if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;


  if( pUpper ) *pRangeDiv *= (double)4;


  return rc;
}

#ifdef SQLITE4_ENABLE_STAT3
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
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
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereEqualScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  tRowcnt *pnRow       /* Write the revised row estimate here */
){
  sqlite4_buffer buf;       /* Encoded on right-hand side of pTerm */
  u8 aff;                   /* Column affinity */
  int rc;                   /* Subfunction return code */
  tRowcnt a[2];             /* Statistics */

  assert( p->aSample!=0 );
  assert( p->nSample>0 );

  sqlite4_buffer_init(&buf, pParse->db->pEnv->pMM);
  aff = p->pTable->aCol[p->aiColumn[0]].affinity;
  if( pExpr ){
    KeyInfo keyinfo;
    rc = whereSampleKeyinfo(pParse, p, &keyinfo);
    if( rc==SQLITE4_OK ){
      rc = valueFromExpr(pParse, &keyinfo, pExpr, aff, &buf);
      if( rc==SQLITE4_OK && buf.n==0 ) rc = SQLITE4_NOTFOUND;
    }
  }else{
    /* Populate the buffer with a NULL. */
    u8 aNull[2] = {0x05, 0xfa};        /* ASC, DESC */
    rc = sqlite4_buffer_set(&buf, &aNull[p->aSortOrder[0]], 1);
  }


  if( rc==SQLITE4_OK ){
    rc = whereKeyStats(pParse, p, &buf, 0, a);
    if( rc==SQLITE4_OK ){
      WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
      *pnRow = a[1];
    }
  }
whereEqualScanEst_cancel:
  sqlite4_buffer_clear(&buf);
  return rc;
}
#endif /* defined(SQLITE4_ENABLE_STAT3) */








|

|






>







|






>

<
|
|
|
|
<







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
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereEqualScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  double *pnRow        /* Write the revised row estimate here */
){
  sqlite4_buffer buf;
  u8 aff;                   /* Column affinity */
  int rc;                   /* Subfunction return code */
  tRowcnt a[2];             /* Statistics */

  assert( p->aSample!=0 );
  assert( p->nSample>0 );

  sqlite4_buffer_init(&buf, pParse->db->pEnv->pMM);
  aff = p->pTable->aCol[p->aiColumn[0]].affinity;
  if( pExpr ){
    KeyInfo keyinfo;
    rc = whereSampleKeyinfo(pParse, p, &keyinfo);
    if( rc==SQLITE4_OK ){
      rc = valueFromExpr(pParse, &keyinfo, pExpr, aff, &buf);
      if( buf.n==0 ) return SQLITE4_NOTFOUND;
    }
  }else{
    /* Populate the buffer with a NULL. */
    u8 aNull[2] = {0x05, 0xfa};        /* ASC, DESC */
    rc = sqlite4_buffer_set(&buf, &aNull[p->aSortOrder[0]], 1);
  }
  if( rc ) goto whereEqualScanEst_cancel;


  rc = whereKeyStats(pParse, p, &buf, 0, a);
  if( rc==SQLITE4_OK ){
    WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
    *pnRow = a[1];

  }
whereEqualScanEst_cancel:
  sqlite4_buffer_clear(&buf);
  return rc;
}
#endif /* defined(SQLITE4_ENABLE_STAT3) */

2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866





















































































































































































































































































































































































































































































































































































2867
2868
2869
2870
2871
2872
2873
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereInScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  tRowcnt *pnRow       /* Write the revised row estimate here */
){
  int rc = SQLITE4_OK;     /* Subfunction return code */
  tRowcnt nEst;           /* Number of rows for a single term */
  tRowcnt nRowEst = 0;    /* New estimate of the number of rows */
  int i;                  /* Loop counter */

  assert( p->aSample!=0 );
  for(i=0; rc==SQLITE4_OK && i<pList->nExpr; i++){
    nEst = p->aiRowEst[0];
    rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
    nRowEst += nEst;
  }
  if( rc==SQLITE4_OK ){
    if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
    *pnRow = nRowEst;
    WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
  }
  return rc;
}
#endif /* defined(SQLITE4_ENABLE_STAT3) */






















































































































































































































































































































































































































































































































































































/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:







|

|
|
|
|










|




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







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
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
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
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
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
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
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
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
3188
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
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
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
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
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
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
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereInScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  double *pnRow        /* Write the revised row estimate here */
){
  int rc = SQLITE4_OK;         /* Subfunction return code */
  double nEst;                /* Number of rows for a single term */
  double nRowEst = (double)0; /* New estimate of the number of rows */
  int i;                      /* Loop counter */

  assert( p->aSample!=0 );
  for(i=0; rc==SQLITE4_OK && i<pList->nExpr; i++){
    nEst = p->aiRowEst[0];
    rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
    nRowEst += nEst;
  }
  if( rc==SQLITE4_OK ){
    if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
    *pnRow = nRowEst;
    WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
  }
  return rc;
}
#endif /* defined(SQLITE4_ENABLE_STAT3) */

/*
** Try to find a MATCH expression that constrains the pTabItem table in the
** WHERE clause. If one exists, set *piTerm to the index in the pWC->a[] array
** and return non-zero. If no such expression exists, return 0.
*/
static int findMatchExpr(
  Parse *pParse, 
  WhereClause *pWC, 
  SrcListItem *pTabItem, 
  int *piTerm
){
  int i;
  int iCsr = pTabItem->iCursor;

  for(i=0; i<pWC->nTerm; i++){
    Expr *pMatch = pWC->a[i].pExpr;
    if( pMatch->iTable==iCsr && pMatch->op==TK_MATCH ) break;
  }
  if( i==pWC->nTerm ) return 0;

  *piTerm = i;
  return 1;
}

static int bestMatchIdx(
  Parse *pParse, 
  WhereClause *pWC, 
  SrcListItem *pTabItem, 
  Bitmask notReady, 
  WhereCost *pCost
){
  int iTerm;

  if( 0==findMatchExpr(pParse, pWC, pTabItem, &iTerm) ) return 0;

  /* Check that the MATCH expression is not composed using values from any
  ** tables that are not ready. If it does, return 0. */
  if( notReady & pWC->a[iTerm].prereqAll ) return 0;

  pCost->used = pWC->a[iTerm].prereqAll;
  pCost->rCost = 1.0;
  pCost->plan.wsFlags = WHERE_INDEXED;
  pCost->plan.nEq = 0;
  pCost->plan.nRow = 10;
  pCost->plan.u.pIdx = pWC->a[iTerm].pExpr->pIdx;
  return 1;
}

/*
** 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.
** Factors that influence cost include:
**
**    *  The estimated number of rows that will be retrieved.  (The
**       fewer the better.)
**
**    *  Whether or not sorting must occur.
**
**    *  Whether or not there must be separate lookups in the
**       index and in the main table.
**
** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
** the SQL statement, then this function only considers plans using the 
** named index. If no such plan is found, then the returned cost is
** SQLITE4_BIG_DBL. If a plan is found that uses the named index, 
** then the cost is calculated in the usual way.
**
** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table 
** in the SELECT statement, then no indexes are considered. However, the 
** selected plan may still take advantage of the built-in rowid primary key
** index.
*/
static void bestKVIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  SrcListItem *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors not available for indexing */
  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 = SQLITE4_BIG_DBL;
  pPk = sqlite4FindPrimaryKey(pSrc->pTab, 0);

  /* 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
  ** because columns might end up being NULL if the table does not match -
  ** a circumstance which the index cannot help us discover.  Ticket #2177.
  */
  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.  
  */
  if( pSrc->notIndexed ){
    pFirst = pPk;
  }else if( pSrc->pIndex ){
    pFirst = pSrc->pIndex;
  }else{
    pFirst = pSrc->pTab->pIndex;
  }
  eqTermMask = idxEqTermMask;

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

    /* The following variables are populated based on the properties of
    ** index being evaluated. They are then used to determine the expected
    ** cost and number of rows returned.
    **
    **  nEq: 
    **    Number of equality terms that can be implemented using the index.
    **    In other words, the number of initial fields in the index that
    **    are used in == or IN or NOT NULL constraints of the WHERE clause.
    **
    **  nInMul:  
    **    The "in-multiplier". This is an estimate of how many seek operations 
    **    SQLite must perform on the index in question. For example, if the 
    **    WHERE clause is:
    **
    **      WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
    **
    **    SQLite must perform 9 lookups on an index on (a, b), so nInMul is 
    **    set to 9. Given the same schema and either of the following WHERE 
    **    clauses:
    **
    **      WHERE a =  1
    **      WHERE a >= 2
    **
    **    nInMul is set to 1.
    **
    **    If there exists a WHERE term of the form "x IN (SELECT ...)", then 
    **    the sub-select is assumed to return 25 rows for the purposes of 
    **    determining nInMul.
    **
    **  bInEst:  
    **    Set to true if there was at least one "x IN (SELECT ...)" term used 
    **    in determining the value of nInMul.  Note that the RHS of the
    **    IN operator must be a SELECT, not a value list, for this variable
    **    to be true.
    **
    **  rangeDiv:
    **    An estimate of a divisor by which to reduce the search space due
    **    to inequality constraints.  In the absence of sqlite_stat3 ANALYZE
    **    data, a single inequality reduces the search space to 1/4rd its
    **    original size (rangeDiv==4).  Two inequalities reduce the search
    **    space to 1/16th of its original size (rangeDiv==16).
    **
    **  bSort:   
    **    Boolean. True if there is an ORDER BY clause that will require an 
    **    external sort (i.e. scanning the index being evaluated will not 
    **    correctly order records).
    **
    **  bLookup: 
    **    Boolean. True if a table lookup is required for each index entry
    **    visited.  In other words, true if this is not a covering index.
    **    This is always false for the rowid primary key index of a table.
    **    For other indexes, it is true unless all the columns of the table
    **    used by the SELECT statement are present in the index (such an
    **    index is sometimes described as a covering index).
    **    For example, given the index on (a, b), the second of the following 
    **    two queries requires table b-tree lookups in order to find the value
    **    of column c, but the first does not because columns a and b are
    **    both available in the index.
    **
    **             SELECT a, b    FROM tbl WHERE a = 1;
    **             SELECT a, b, c FROM tbl WHERE a = 1;
    */
    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 SQLITE4_ENABLE_STAT3
    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
#endif
    int nCol = pProbe->nColumn;   /* Total columns in index record */

    if( pProbe->eIndexType==SQLITE4_INDEX_FTS5 ) continue;

    /* 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;
          bInEst = 1;
        }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
          /* "x IN (value, value, ...)" */
          nInMul *= pExpr->x.pList->nExpr;
        }
      }else if( pTerm->eOperator & WO_ISNULL ){
        wsFlags |= WHERE_COLUMN_NULL;
      }
#ifdef SQLITE4_ENABLE_STAT3
      if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
#endif
      used |= pTerm->prereqRight;
    }
 
    /* If the index being considered is UNIQUE, and there is an equality 
    ** constraint for all columns in the index, then this search will find
    ** 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->fIndex & IDX_Unordered)==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!=SQLITE4_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] ){
      nRow = aiRowEst[0]/2;
      nInMul = (int)(nRow / aiRowEst[nEq]);
    }

#ifdef SQLITE4_ENABLE_STAT3
    /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
    ** and we do not think that values of x are unique and if histogram
    ** data is available for column x, then it might be possible
    ** to get a better estimate on the number of rows based on
    ** VALUE and how common that value is according to the histogram.
    */
    if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
      assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
      if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
        testcase( pFirstTerm->eOperator==WO_EQ );
        testcase( pFirstTerm->eOperator==WO_ISNULL );
        whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
      }else if( bInEst==0 ){
        assert( pFirstTerm->eOperator==WO_IN );
        whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
      }
    }
#endif /* SQLITE4_ENABLE_STAT3 */

    /* Adjust the number of output rows and downward to reflect rows
    ** that are excluded by range constraints.
    */
    nRow = nRow/rangeDiv;
    if( nRow<1 ) nRow = 1;

    /* Experiments run on real SQLite databases show that the time needed
    ** to do a binary search to locate a row in a table or index is roughly
    ** log10(N) times the time to move from one row to the next row within
    ** a table or index.  The actual times can vary, with the size of
    ** records being an important factor.  Both moves and searches are
    ** slower with larger records, presumably because fewer records fit
    ** on one page and hence more pages have to be fetched.
    **
    ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do
    ** not give us data on the relative sizes of table and index records.
    ** So this computation assumes table records are about twice as big
    ** as index records
    */
    if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){
      /* The cost of a full table scan is a number of move operations equal
      ** to the number of rows in the table.
      **
      ** We add an additional 4x penalty to full table scans.  This causes
      ** the cost function to err on the side of choosing an index over
      ** choosing a full scan.  This 4x full-scan penalty is an arguable
      ** 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
    ** adds C*N*log10(N) to the cost, where N is the number of rows to be 
    ** sorted and C is a factor between 1.95 and 4.3.  We will split the
    ** difference and select C of 3.0.
    */
    if( bSort ){
      cost += nRow*estLog(nRow)*3;
    }
    if( bDist ){
      cost += nRow*estLog(nRow)*3;
    }

    /**** Cost of using this index has now been computed ****/

    /* If there are additional constraints on this table that cannot
    ** be used with the current index, but which might lower the number
    ** of output rows, adjust the nRow value accordingly.  This only 
    ** matters if the current index is the least costly, so do not bother
    ** with this step if we already know this index will not be chosen.
    ** Also, never reduce the output row count below 2 using this step.
    **
    ** It is critical that the notValid mask be used here instead of
    ** the notReady mask.  When computing an "optimal" index, the notReady
    ** mask will only have one bit set - the bit for the current table.
    ** The notValid mask, on the other hand, always has all bits set for
    ** tables that are not in outer loops.  If notReady is used here instead
    ** of notValid, then a optimal index that depends on inner joins loops
    ** might be selected even when there exists an optimal index that has
    ** no such dependency.
    */
    if( nRow>2 && cost<=pCost->rCost ){
      int k;                       /* Loop counter */
      int nSkipEq = nEq;           /* Number of == constraints to skip */
      int nSkipRange = nBound;     /* Number of < constraints to skip */
      Bitmask thisTab;             /* Bitmap for pSrc */

      thisTab = getMask(pWC->pMaskSet, iCur);
      for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){
        if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
        if( (pTerm->prereqAll & notValid)!=thisTab ) continue;
        if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
          if( nSkipEq ){
            /* Ignore the first nEq equality matches since the index
            ** has already accounted for these */
            nSkipEq--;
          }else{
            /* Assume each additional equality match reduces the result
            ** set size by a factor of 10 */
            nRow /= 10;
          }
        }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
          if( nSkipRange ){
            /* Ignore the first nSkipRange range constraints since the index
            ** has already accounted for these */
            nSkipRange--;
          }else{
            /* Assume each additional range constraint reduces the result
            ** set size by a factor of 3.  Indexed range constraints reduce
            ** the search space by a larger factor: 4.  We make indexed range
            ** more selective intentionally because of the subjective 
            ** observation that indexed range constraints really are more
            ** selective in practice, on average. */
            nRow /= 3;
          }
        }else if( pTerm->eOperator!=WO_NOOP ){
          /* Any other expression lowers the output row count by half */
          nRow /= 2;
        }
      }
      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;
  }

  /* If there is no ORDER BY clause and the SQLITE4_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 & SQLITE4_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" : 
         pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
  ));
  
  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
  bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost);
  pCost->plan.wsFlags |= eqTermMask;
}

/*
** Find the query plan for accessing table pSrc->pTab. Write the
** best query plan and its cost into the WhereCost object supplied 
** as the last parameter. This function may calculate the cost of
** both real and virtual table scans.
*/
static void bestIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  SrcListItem *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors not available for indexing */
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  WhereCost *pCost            /* Lowest cost query plan */
){
#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if( IsVirtual(pSrc->pTab) ){
    sqlite4_index_info *p = 0;
    bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p);
    if( p->needToFreeIdxStr ){
      sqlite4_free(p->idxStr);
    }
    sqlite4DbFree(pParse->db, p);
  }else
#endif
  {
    bestKVIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost);
  }
}

/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
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
3027
3028
3029
3030
** For a constraint of the form X=expr, the expression is evaluated and its
** result is left on the stack.  For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static int codeEqualityTerm(
  Parse *pParse,      /* The parsing context */
  WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
  WhereLevel *pLevel, /* The level of the FROM clause we are working on */
  int iEq,            /* Index of the equality term within this level */
  int bRev,           /* True for reverse-order IN operations */
  int iTarget         /* Attempt to leave results in this register */
){
  Expr *pX = pTerm->pExpr;
  Vdbe *v = pParse->pVdbe;
  int iReg;                  /* Register holding results */

  assert( iTarget>0 );
  if( pX->op==TK_EQ ){
    iReg = sqlite4ExprCodeTarget(pParse, pX->pRight, iTarget);
  }else if( pX->op==TK_ISNULL ){
    iReg = iTarget;
    sqlite4VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE4_OMIT_SUBQUERY
  }else{








    int eType;






    int iTab;
    int iCov;
    struct InLoop *pIn;
    WhereLoop *pLoop = pLevel->pWLoop;

    if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
      && pLoop->u.btree.pIndex!=0
      && pLoop->u.btree.pIndex->aSortOrder[iEq]
    ){
      testcase( iEq==0 );
      testcase( bRev );
      bRev = !bRev;
    }
    assert( pX->op==TK_IN );
    iReg = iTarget;
    eType = sqlite4FindInIndex(pParse, pX, 0, &iCov);
    if( eType==IN_INDEX_INDEX_DESC ){
      testcase( bRev );
      bRev = !bRev;
    }




















    iTab = pX->iTable;


    sqlite4VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
    pLoop->wsFlags |= WHERE_IN_ABLE;
    if( pLevel->u.in.nIn==0 ){
      pLevel->addrNxt = sqlite4VdbeMakeLabel(v);
    }
    pLevel->u.in.nIn++;
    pLevel->u.in.aInLoop =
       sqlite4DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);

    pIn = pLevel->u.in.aInLoop;

    if( pIn ){
      pIn += pLevel->u.in.nIn - 1;
      pIn->iCur = iTab;
      if( eType==IN_INDEX_ROWID ){
        pIn->addrInTop = sqlite4VdbeAddOp2(v, OP_Rowid, iTab, iReg);
      }else{
        pIn->addrInTop = sqlite4VdbeAddOp3(v, OP_Column, iTab, iCov, iReg);
      }
      pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
      sqlite4VdbeAddOp1(v, OP_IsNull, iReg);
    }else{

      pLevel->u.in.nIn = 0;
    }
#endif
  }
  disableTerm(pLevel, pTerm);
  return iReg;
}







|
<
<














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

|

<

<
<
<
<
<
<
<
<


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

|
<
|
>

>



<
<
<
|
<
<


>







3486
3487
3488
3489
3490
3491
3492
3493


3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525

3526








3527
3528




3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556


3557
3558

3559
3560
3561
3562
3563
3564
3565



3566


3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
** For a constraint of the form X=expr, the expression is evaluated and its
** result is left on the stack.  For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static int codeEqualityTerm(
  Parse *pParse,      /* The parsing context */
  WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
  WhereLevel *pLevel, /* When level of the FROM clause we are working on */


  int iTarget         /* Attempt to leave results in this register */
){
  Expr *pX = pTerm->pExpr;
  Vdbe *v = pParse->pVdbe;
  int iReg;                  /* Register holding results */

  assert( iTarget>0 );
  if( pX->op==TK_EQ ){
    iReg = sqlite4ExprCodeTarget(pParse, pX->pRight, iTarget);
  }else if( pX->op==TK_ISNULL ){
    iReg = iTarget;
    sqlite4VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE4_OMIT_SUBQUERY
  }else{
    /* Code a loop that iterates through the set of distinct, non-null 
    ** values in the set on the right-hand-side of the IN(...) operator.
    ** There are two ways to do this:
    **
    **   * If the SELECT statement is of the form "SELECT x FROM tbl", 
    **     and column x is subject to a UNIQUE constraint, and the 
    **     default affinity and collation sequence of column "x" match
    **     those required by the comparison, iterate through the PK
    **     index.
    **
    **   * Otherwise, materialize the set into an ephemeral index using
    **     "x" as both the key and value. Then loop through the contents
    **     of the ephemeral index.
    */
    sqlite4 *db = pParse->db;
    int iTab;
    int iCol;                     /* Column to read from cursor iTab */
    struct InLoop *pIn;










    assert( pX->op==TK_IN );
    iReg = iTarget;





    if( sqlite4FindExistingInIndex(pParse, pX, 1) ){
      /* This branch is taken if the rhs of the IN is a select of the
      ** form "SELECT x FROM tble" and column x is subject to a UNIQUE 
      ** constraint that uses the same collation sequence and affinity as
      ** this IN (...) test. In this case just loop through all values of
      ** "x", skipping any NULLs.  */
      Table *pTab = pX->x.pSelect->pSrc->a[0].pTab;
      int iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
      iTab = pX->iTable = pParse->nTab++;
      sqlite4OpenPrimaryKey(pParse, iTab, iDb, pTab, OP_OpenRead);
      iCol = pX->pLeft->iColumn;
    }else{
      /* Set Parse.nQueryLoop to 1 before calling sqlite4CodeSubselect().
      ** This informs the optimizer that there is no point in constructing
      ** any automatic indexes for the outer loop of the sub-select, as it
      ** will only be run once. See also bestAutomaticIndex().  */
      int nQueryLoopSave = pParse->nQueryLoop;
      pParse->nQueryLoop = (double)1;
      sqlite4CodeSubselect(pParse, pX, 0, 0);
      pParse->nQueryLoop = nQueryLoopSave;
      iTab = pX->iTable;
      iCol = 0;
    }
    sqlite4VdbeAddOp2(v, OP_Rewind, iTab, 0);
    assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );

    if( pLevel->u.in.nIn==0 ) pLevel->addrNxt = sqlite4VdbeMakeLabel(v);


    pLevel->u.in.nIn++;
    pLevel->u.in.aInLoop = sqlite4DbReallocOrFree(db, pLevel->u.in.aInLoop, 

        (sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn)
    );
    pIn = pLevel->u.in.aInLoop;

    if( pIn ){
      pIn += pLevel->u.in.nIn - 1;
      pIn->iCur = iTab;



      pIn->addrInTop = sqlite4VdbeAddOp3(v, OP_Column, iTab, iCol, iReg);


      sqlite4VdbeAddOp1(v, OP_IsNull, iReg);
    }else{
      assert( db->mallocFailed );
      pLevel->u.in.nIn = 0;
    }
#endif
  }
  disableTerm(pLevel, pTerm);
  return iReg;
}
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
** no conversion should be attempted before using a t2.b value as part of
** a key to search the index. Hence the first byte in the returned affinity
** string in this example would be set to SQLITE4_AFF_NONE.
*/
static int codeAllEqualityTerms(
  Parse *pParse,        /* Parsing context */
  WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
  int bRev,             /* Reverse the order of IN operators */

  int nExtraReg,        /* Number of extra registers to allocate */
  char **pzAff          /* OUT: Set to point to affinity string */
){
  int nEq;                      /* The number of == or IN constraints to code */
  Vdbe *v = pParse->pVdbe;      /* The vm under construction */
  Index *pIdx;                  /* The index being used for this loop */

  WhereTerm *pTerm;             /* A single constraint term */
  WhereLoop *pLoop;             /* The WhereLoop object */
  int j;                        /* Loop counter */
  int regBase;                  /* Base register */
  int nReg;                     /* Number of registers to allocate */
  char *zAff;                   /* Affinity string to return */

  /* This module is only called on query plans that use an index. */
  pLoop = pLevel->pWLoop;
  assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
  nEq = pLoop->u.btree.nEq;
  pIdx = pLoop->u.btree.pIndex;
  assert( pIdx!=0 );

  /* Figure out how many memory cells we will need then allocate them.
  */
  regBase = pParse->nMem + 1;
  nReg = pLoop->u.btree.nEq + nExtraReg;
  pParse->nMem += nReg;

  zAff = sqlite4DbStrDup(pParse->db, sqlite4IndexAffinityStr(v, pIdx));
  if( !zAff ){
    pParse->db->mallocFailed = 1;
  }

  /* Evaluate the equality constraints
  */
  assert( idxColumnCount(pIdx, sqlite4FindPrimaryKey(pIdx->pTable, 0))>=nEq );
  for(j=0; j<nEq; j++){
    int r1;

    pTerm = pLoop->aLTerm[j];
    assert( pTerm!=0 );
    /* The following true for indices with redundant columns. 
    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
    if( r1!=regBase+j ){
      if( nReg==1 ){
        sqlite4ReleaseTempReg(pParse, regBase);
        regBase = r1;
      }else{
        sqlite4VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
      }







|
>



|


>

<






<
|
<
|
<




|









|


>
|
|




|







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
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
** no conversion should be attempted before using a t2.b value as part of
** a key to search the index. Hence the first byte in the returned affinity
** string in this example would be set to SQLITE4_AFF_NONE.
*/
static int codeAllEqualityTerms(
  Parse *pParse,        /* Parsing context */
  WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
  WhereClause *pWC,     /* The WHERE clause */
  Bitmask notReady,     /* Which parts of FROM have not yet been coded */
  int nExtraReg,        /* Number of extra registers to allocate */
  char **pzAff          /* OUT: Set to point to affinity string */
){
  int nEq = pLevel->plan.nEq;   /* The number of == or IN constraints to code */
  Vdbe *v = pParse->pVdbe;      /* The vm under construction */
  Index *pIdx;                  /* The index being used for this loop */
  int iCur = pLevel->iTabCur;   /* The cursor of the table */
  WhereTerm *pTerm;             /* A single constraint term */

  int j;                        /* Loop counter */
  int regBase;                  /* Base register */
  int nReg;                     /* Number of registers to allocate */
  char *zAff;                   /* Affinity string to return */

  /* This module is only called on query plans that use an index. */

  assert( pLevel->plan.wsFlags & WHERE_INDEXED );

  pIdx = pLevel->plan.u.pIdx;


  /* Figure out how many memory cells we will need then allocate them.
  */
  regBase = pParse->nMem + 1;
  nReg = pLevel->plan.nEq + nExtraReg;
  pParse->nMem += nReg;

  zAff = sqlite4DbStrDup(pParse->db, sqlite4IndexAffinityStr(v, pIdx));
  if( !zAff ){
    pParse->db->mallocFailed = 1;
  }

  /* Evaluate the equality constraints
  */
  assert( pIdx->nColumn>=nEq );
  for(j=0; j<nEq; j++){
    int r1;
    int k = pIdx->aiColumn[j];
    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
    if( NEVER(pTerm==0) ) break;
    /* The following true for indices with redundant columns. 
    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
    if( r1!=regBase+j ){
      if( nReg==1 ){
        sqlite4ReleaseTempReg(pParse, regBase);
        regBase = r1;
      }else{
        sqlite4VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
      }
3178
3179
3180
3181
3182
3183
3184
3185

3186

3187
3188
3189
3190
3191
3192

3193
3194
3195
3196
3197


3198
3199

3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230

3231
3232
3233
3234

3235
3236
3237
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

3263
3264
3265
3266
3267
3268
3269
3270
3271


3272
3273
3274
3275

3276
3277
3278
3279
3280
3281
3282

3283
3284
3285
3286






3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
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
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
**
**   "a=? AND b>?"
**
** The returned pointer points to memory obtained from sqlite4DbMalloc().
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
static char *explainIndexRange(sqlite4 *db, WhereLoop *pLoop, Table *pTab){

  Index *pIndex = pLoop->u.btree.pIndex;

  int nEq = pLoop->u.btree.nEq;
  int i, j;
  Column *aCol = pTab->aCol;
  int *aiColumn = pIndex->aiColumn;
  StrAccum txt;


  if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
    return 0;
  }
  sqlite4StrAccumInit(&txt, 0, 0, SQLITE4_MAX_LENGTH);
  txt.db = db;


  sqlite4StrAccumAppend(&txt, " (", 2);
  for(i=0; i<nEq; i++){

    explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
  }

  j = i;
  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
    char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(&txt, i++, z, ">");
  }
  if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
    char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(&txt, i, z, "<");
  }
  sqlite4StrAccumAppend(&txt, ")", 1);
  return sqlite4StrAccumFinish(&txt);
}

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
** record is added to the output to describe the table scan strategy in 
** pLevel.
*/
static void explainOneScan(
  Parse *pParse,                  /* Parse context */
  SrcList *pTabList,              /* Table list this loop refers to */
  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
  int iLevel,                     /* Value for "level" column of output */
  int iFrom,                      /* Value for "from" column of output */
  u16 wctrlFlags                  /* Flags passed to sqlite4WhereBegin() */
){
  if( pParse->explain==2 ){

    struct SrcListItem *pItem = &pTabList->a[pLevel->iFrom];
    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
    sqlite4 *db = pParse->db;     /* Database handle */
    char *zMsg;                   /* Text to add to EQP output */

    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
    int isSearch;                 /* True for a SEARCH. False for SCAN. */
    WhereLoop *pLoop;             /* The controlling WhereLoop object */
    u32 flags;                    /* Flags that describe this loop */

    pLoop = pLevel->pWLoop;
    flags = pLoop->wsFlags;
    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;


    isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
            || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
            || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));

    zMsg = sqlite4MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
    if( pItem->pSelect ){
      zMsg = sqlite4MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
    }else{
      zMsg = sqlite4MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
    }

    if( pItem->zAlias ){
      zMsg = sqlite4MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
    }
    if( (flags & WHERE_VIRTUALTABLE)==0
     && ALWAYS(pLoop->u.btree.pIndex!=0)
    ){
      char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
      Index *pIdx = pLoop->u.btree.pIndex;

      if( flags & WHERE_AUTO_INDEX ){
        zMsg = sqlite4MAppendf(db, zMsg, "%s USING AUTOMATIC COVERING INDEX%s",
            zMsg, zWhere
        );
      }else if( pIdx->eIndexType==SQLITE4_INDEX_PRIMARYKEY ){
        if( isSearch ){
          zMsg = sqlite4MAppendf(db, zMsg, "%s USING PRIMARY KEY%s",
              zMsg, zWhere
          );


        }
      }else{
        const char *zCover = (flags & WHERE_IDX_ONLY) ? " COVERING" : "";
        zMsg = sqlite4MAppendf(db, zMsg, "%s USING%s INDEX %s%s",

            zMsg, zCover, pIdx->zName, zWhere
        );
      }
      sqlite4DbFree(db, zWhere);
    }
#ifndef SQLITE4_OMIT_VIRTUALTABLE
    else if( (flags & WHERE_VIRTUALTABLE)!=0 ){

      zMsg = sqlite4MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
    }
#endif






    zMsg = sqlite4MAppendf(db, zMsg, "%s", zMsg);
    sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE4_OMIT_EXPLAIN */


/*
** Try to find a MATCH expression that constrains the pTabItem table in the
** WHERE clause. If one exists, set *piTerm to the index in the pWC->a[] array
** and return non-zero. If no such expression exists, return 0.
*/
static int findMatchExpr(
  WhereClause *pWC, 
  SrcListItem *pTabItem, 
  int *piTerm
){
  int i;
  int iCsr = pTabItem->iCursor;

  for(i=0; i<pWC->nTerm; i++){
    Expr *pMatch = pWC->a[i].pExpr;
    if( pMatch->iTable==iCsr && pMatch->op==TK_MATCH ) break;
  }
  if( i==pWC->nTerm ) return 0;

  *piTerm = i;
  return 1;
}


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

  Bitmask notReady     /* Which tables are currently available */

){
  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 */
  WhereLoop *pLoop;    /* The WhereLoop object being 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 SrcListItem *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Bitmask newNotReady;      /* Return value */

  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = &pWInfo->sWC;
  pLevel = &pWInfo->a[iLevel];
  pLoop = pLevel->pWLoop;
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  bRev = (pWInfo->revMask>>iLevel)&1;
  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
           && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
  VdbeNoopComment((v, "Begin Join Loop %d", iLevel));

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







|
>
|
>
|
|
<
<


>
|




>
>


>
|

<
<
|
|
|

|
|
|




















>
|



>


<
<

<
<


>
|
<
|











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




>

|


>
>
>
>
>
>
|






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








>
|
>




<


<




|


<
|
<



|

<


<
|
<
<







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
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785


3786


3787
3788
3789
3790

3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803


3804
3805
3806
3807
3808


3809

3810


3811
3812
3813


3814
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
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854

3855
3856

3857
3858
3859
3860
3861
3862
3863

3864

3865
3866
3867
3868
3869

3870
3871

3872


3873
3874
3875
3876
3877
3878
3879
**
**   "a=? AND b>?"
**
** The returned pointer points to memory obtained from sqlite4DbMalloc().
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
static char *explainIndexRange(sqlite4 *db, WhereLevel *pLevel, Table *pTab){
  WherePlan *pPlan = &pLevel->plan;
  Index *pPk;
  Index *pIdx = pPlan->u.pIdx;
  int nEq = pPlan->nEq;
  int i;


  StrAccum txt;

  pPk = sqlite4FindPrimaryKey(pTab, 0);
  if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
    return 0;
  }
  sqlite4StrAccumInit(&txt, 0, 0, SQLITE4_MAX_LENGTH);
  txt.db = db;
  txt.pEnv = db->pEnv;

  sqlite4StrAccumAppend(&txt, " (", 2);
  for(i=0; i<nEq; i++){
    const char *zCol = tblColumnName(pTab, idxColumnNumber(pIdx, pPk, i));
    explainAppendTerm(&txt, i, zCol, "=");
  }


  if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
    const char *zCol = tblColumnName(pTab, idxColumnNumber(pIdx, pPk, nEq));
    explainAppendTerm(&txt, i++, zCol, ">");
  }
  if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
    const char *zCol = tblColumnName(pTab, idxColumnNumber(pIdx, pPk, nEq));
    explainAppendTerm(&txt, i, zCol, "<");
  }
  sqlite4StrAccumAppend(&txt, ")", 1);
  return sqlite4StrAccumFinish(&txt);
}

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
** record is added to the output to describe the table scan strategy in 
** pLevel.
*/
static void explainOneScan(
  Parse *pParse,                  /* Parse context */
  SrcList *pTabList,              /* Table list this loop refers to */
  WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
  int iLevel,                     /* Value for "level" column of output */
  int iFrom,                      /* Value for "from" column of output */
  u16 wctrlFlags                  /* Flags passed to sqlite4WhereBegin() */
){
  if( pParse->explain==2 ){
    u32 flags = pLevel->plan.wsFlags;
    SrcListItem *pItem = &pTabList->a[pLevel->iFrom];
    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
    sqlite4 *db = pParse->db;     /* Database handle */
    char *zMsg;                   /* Text to add to EQP output */
    sqlite4_int64 nRow;           /* Expected number of rows visited by scan */
    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
    int isSearch;                 /* True for a SEARCH. False for SCAN. */





    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;

    isSearch = (pLevel->plan.nEq>0)
             || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0

             || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));

    zMsg = sqlite4MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
    if( pItem->pSelect ){
      zMsg = sqlite4MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
    }else{
      zMsg = sqlite4MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
    }

    if( pItem->zAlias ){
      zMsg = sqlite4MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
    }
    if( (flags & WHERE_INDEXED)!=0 ){


      char *zWhere = explainIndexRange(db, pLevel, pItem->pTab);
      Index *pIdx = pLevel->plan.u.pIdx;
      const char *zName = "";
      const char *zType = "INDEX";



      if( pIdx->eIndexType==SQLITE4_INDEX_PRIMARYKEY ){

        zType = "PRIMARY KEY";


      }else if( 0==(flags & WHERE_TEMP_INDEX) ){
        zName = pIdx->zName;
      }


      zMsg = sqlite4MAppendf(db, zMsg, "%s USING %s%s%s%s%s", zMsg, 
          ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
          zType, (zName[0] ? " " : ""), zName, zWhere
      );

      sqlite4DbFree(db, zWhere);
    }
#ifndef SQLITE4_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);
    }
#endif
    if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
      testcase( wctrlFlags & WHERE_ORDERBY_MIN );
      nRow = 1;
    }else{
      nRow = (sqlite4_int64)pLevel->plan.nRow;
    }
    zMsg = sqlite4MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
    sqlite4VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
  }
}
#else
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE4_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 */
  SrcListItem *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrCont;                   /* Jump here to continue with next cycle */

  int iReleaseReg = 0;            /* Temp register to free before returning */


  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
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424




3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437

3438
3439


3440
3441
3442
3443
3444
3445
3446
3447

3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
  */
  if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
    pLevel->iLeftJoin = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
    VdbeComment((v, "init LEFT JOIN no-match flag"));
  }

#if 0
  /* Special case of a FROM clause subquery implemented as a co-routine */
  if( pTabItem->viaCoroutine ){
    int regYield = pTabItem->regReturn;
    sqlite4VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
    pLevel->p2 =  sqlite4VdbeAddOp1(v, OP_Yield, regYield);
    VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
    sqlite4VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
    pLevel->op = OP_Goto;
  }else
#endif

  if( (pLoop->wsFlags & WHERE_INDEXED)
   && (pLoop->u.btree.pIndex->eIndexType==SQLITE4_INDEX_FTS5)
  ){
    /* Case -1:  An FTS query */
    int iTerm;
    int rMatch;
    int rFree;
    findMatchExpr(pWC, pTabItem, &iTerm);

    rMatch = sqlite4ExprCodeTemp(pParse, pWC->a[iTerm].pExpr->pRight, &rFree);
    pWC->a[iTerm].wtFlags |= TERM_CODED;
    sqlite4Fts5CodeQuery(pParse, 
        pLoop->u.btree.pIndex, pLevel->iIdxCur, addrBrk, rMatch
    );
    sqlite4VdbeChangeP5(v, bRev);
    sqlite4ReleaseTempReg(pParse, rFree);

    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4VdbeAddOp3(v, OP_SeekPk, iCur, 0, pLevel->iIdxCur);
    pLevel->op = OP_FtsNext;
    pLevel->p1 = pLevel->iIdxCur;
  }else

#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
    /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
    **          to access the data.
    */
    int iReg;   /* P3 Value for OP_VFilter */
    int addrNotFound;
    int nConstraint = pLoop->nLTerm;





    sqlite4ExprCachePush(pParse);
    iReg = sqlite4GetTempRange(pParse, nConstraint+2);
    addrNotFound = pLevel->addrBrk;
    for(j=0; j<nConstraint; j++){
      int iTarget = iReg+j+2;
      pTerm = pLoop->aLTerm[j];
      if( pTerm==0 ) continue;
      if( pTerm->eOperator & WO_IN ){
        codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
        addrNotFound = pLevel->addrNxt;
      }else{
        sqlite4ExprCode(pParse, pTerm->pExpr->pRight, iTarget);

      }
    }


    sqlite4VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
    sqlite4VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
    sqlite4VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
                      pLoop->u.vtab.idxStr,
                      pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
    pLoop->u.vtab.needFree = 0;
    for(j=0; j<nConstraint && j<16; j++){
      if( (pLoop->u.vtab.omitMask>>j)&1 ){

        disableTerm(pLevel, pLoop->aLTerm[j]);
      }
    }
    pLevel->op = OP_VNext;
    pLevel->p1 = iCur;
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2);
    sqlite4ExprCachePop(pParse, 1);
  }else
#endif /* SQLITE4_OMIT_VIRTUALTABLE */

  if( pLoop->wsFlags & WHERE_INDEXED ){
    /* Case 4: 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 
    **         the right-most column can be an inequality - the rest must







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





|




|

<






|
<

|
|



|
|
>
>
>
>



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










|
|







3890
3891
3892
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
  */
  if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
    pLevel->iLeftJoin = ++pParse->nMem;
    sqlite4VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
    VdbeComment((v, "init LEFT JOIN no-match flag"));
  }













  if( (pLevel->plan.wsFlags & WHERE_INDEXED)
   && (pLevel->plan.u.pIdx->eIndexType==SQLITE4_INDEX_FTS5)
  ){
    /* Case -1:  An FTS query */
    int iTerm;
    int rMatch;
    int rFree;
    findMatchExpr(pParse, pWC, pTabItem, &iTerm);

    rMatch = sqlite4ExprCodeTemp(pParse, pWC->a[iTerm].pExpr->pRight, &rFree);
    pWC->a[iTerm].wtFlags |= TERM_CODED;
    sqlite4Fts5CodeQuery(pParse, 
        pLevel->plan.u.pIdx, pLevel->iIdxCur, addrBrk, rMatch
    );

    sqlite4ReleaseTempReg(pParse, rFree);

    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4VdbeAddOp3(v, OP_SeekPk, iCur, 0, pLevel->iIdxCur);
    pLevel->op = OP_FtsNext;
    pLevel->p1 = pLevel->iIdxCur;
  }else 

#ifndef SQLITE4_OMIT_VIRTUALTABLE
  if(  (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
    /* Case 0:  The table is a virtual-table.  Use the VFilter and VNext
    **          to access the data.
    */
    int iReg;   /* P3 Value for OP_VFilter */
    sqlite4_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
    int nConstraint = pVtabIdx->nConstraint;
    struct sqlite4_index_constraint_usage *aUsage =
                                                pVtabIdx->aConstraintUsage;
    const struct sqlite4_index_constraint *aConstraint =
                                                pVtabIdx->aConstraint;

    sqlite4ExprCachePush(pParse);
    iReg = sqlite4GetTempRange(pParse, nConstraint+2);

    for(j=1; j<=nConstraint; j++){
      for(k=0; k<nConstraint; k++){

        if( aUsage[k].argvIndex==j ){
          int iTerm = aConstraint[k].iTermOffset;



          sqlite4ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
          break;
        }
      }
      if( k==nConstraint ) break;
    }
    sqlite4VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
    sqlite4VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
    sqlite4VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,

                      pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
    pVtabIdx->needToFreeIdxStr = 0;
    for(j=0; j<nConstraint; j++){
      if( aUsage[j].omit ){
        int iTerm = aConstraint[j].iTermOffset;
        disableTerm(pLevel, &pWC->a[iTerm]);
      }
    }
    pLevel->op = OP_VNext;
    pLevel->p1 = iCur;
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);
    sqlite4ReleaseTempRange(pParse, iReg, nConstraint+2);
    sqlite4ExprCachePop(pParse, 1);
  }else
#endif /* SQLITE4_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 
    **         the right-most column can be an inequality - the rest must
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568

3569
3570


3571

3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
      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 = pLoop->u.btree.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 endEq;                   /* True if range end uses ==, >= or <= */
    int start_constraints;       /* Start of range is constrained */
    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 = pLoop->u.btree.pIndex;
    pPk = sqlite4FindPrimaryKey(pIdx->pTable, 0);
    iIneq = idxColumnNumber(pIdx, pPk, nEq);
    iIdxCur = pLevel->iIdxCur;
    assert( iCur==pLevel->iTabCur );

    /* 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,
    ** this requires some special handling.
    */
    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
     && (pWInfo->bOBSat!=0)
     && (pIdx->nColumn>nEq)
    ){
      /* 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. 
    */
    j = nEq;
    if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
      pRangeStart = pLoop->aLTerm[j++];
      nExtraReg = 1;
    }
    if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
      pRangeEnd = pLoop->aLTerm[j++];
      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,bRev,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]==SQLITE4_SO_ASC))
     || (bRev && pIdx->nColumn==nEq)
    ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
    }

    testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
    testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
    startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
    endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
    start_constraints = pRangeStart || nEq>0;

    /* Seek the index cursor to the start of the range. */
    nConstraint = nEq;
    if( pRangeStart ){







|
|


















|













|
|









|
<
<
|
|


|
|





|
>

|
>
>

>





|
<






|
|
|
|







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
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057


4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082

4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
      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 endEq;                   /* True if range end uses ==, >= or <= */
    int start_constraints;       /* Start of range is constrained */
    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);
    iIneq = idxColumnNumber(pIdx, pPk, nEq);
    iIdxCur = pLevel->iIdxCur;
    assert( iCur==pLevel->iTabCur );

    /* 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,
    ** this requires some special handling.
    */
    if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
     && (pLevel->plan.wsFlags&WHERE_ORDERBY)
     && (pIdx->nColumn>nEq)
    ){
      /* 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]==SQLITE4_SO_ASC))
     || (bRev && pIdx->nColumn==nEq)
    ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
    }

    testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
    testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
    testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
    testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
    startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
    endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
    start_constraints = pRangeStart || nEq>0;

    /* Seek the index cursor to the start of the range. */
    nConstraint = nEq;
    if( pRangeStart ){
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
3660
3661
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
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
    testcase( op==OP_Rewind );
    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);
    if( nEq<idxColumnCount(pIdx, pPk) ){
      sqlite4VdbeChangeP5(v, OPFLAG_PARTIALKEY);
    }

    /* 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 ){
      /* 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])==SQLITE4_AFF_NONE){
            /* Since the comparison is to be performed with no conversions
            ** applied to the operands, set the affinity to apply to pRight to 
            ** SQLITE4_AFF_NONE.  */
            zEndAff[nEq] = SQLITE4_AFF_NONE;
          }
          if( sqlite4ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
            zEndAff[nEq] = SQLITE4_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;
      if( pIdx->tnum==KVSTORE_ROOT ){
        sqlite4VdbeAddOp2(v, OP_Copy, regBase, regEndKey);
        sqlite4VdbeAddOp1(v, OP_ToBlob, regEndKey);
      }else{
        sqlite4VdbeAddOp4Int(
            v, OP_MakeIdxKey, iIdxCur, regBase, regEndKey, nConstraint
        );
      }

    }

    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!=SQLITE4_INDEX_PRIMARYKEY
     && pIdx->eIndexType!=SQLITE4_INDEX_TEMP
     && 0==(pLoop->wsFlags & WHERE_IDX_ONLY)
    ){
      sqlite4VdbeAddOp3(v, OP_SeekPk, iCur, 0, iIdxCur);
    }

    /* 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( pLoop->wsFlags & WHERE_BTM_LIMIT );
    testcase( pLoop->wsFlags & WHERE_TOP_LIMIT );
    if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
      sqlite4ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iIneq, 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( pLoop->wsFlags & WHERE_ONEROW ){
      pLevel->op = OP_Noop;
    }else if( bRev ){
      pLevel->op = OP_Prev;
    }else{
      pLevel->op = OP_Next;
    }
    pLevel->p1 = iIdxCur;
    if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
      pLevel->p5 = SQLITE4_STMTSTATUS_FULLSCAN_STEP;
    }else{
      assert( pLevel->p5==0 );
    }
  }else

#ifndef SQLITE4_OMIT_OR_OPTIMIZATION
  if( pLoop->wsFlags & WHERE_MULTI_OR ){
    /* Case 5:  Two or more separately indexed terms connected by OR
    **
    ** Example:
    **
    **   CREATE TABLE t1(a,b,c,d);
    **   CREATE INDEX i1 ON t1(a);
    **   CREATE INDEX i2 ON t1(b);
    **   CREATE INDEX i3 ON t1(c);







|















|
|
<











|
|













<
<
<
<
|
|
|
<
<

















<





|
|
<

|
|
|








|







<
<
<
<
|



|
|







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
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
    testcase( op==OP_Rewind );
    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);
    if( (pIdx->nColumn + (pIdx==pPk ? 0 : pPk->nColumn))>nEq ){
      sqlite4VdbeChangeP5(v, OPFLAG_PARTIALKEY);
    }

    /* 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])==SQLITE4_AFF_NONE){
            /* Since the comparison is to be performed with no conversions
             ** applied to the operands, set the affinity to apply to pRight to 
             ** SQLITE4_AFF_NONE.  */
            zEndAff[nEq] = SQLITE4_AFF_NONE;
          }
          if( sqlite4ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
            zEndAff[nEq] = SQLITE4_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;




      sqlite4VdbeAddOp4Int(
          v, OP_MakeIdxKey, iIdxCur, regBase, regEndKey, nConstraint
      );


    }

    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!=SQLITE4_INDEX_PRIMARYKEY
     && pIdx->eIndexType!=SQLITE4_INDEX_TEMP

    ){
      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 ){
      sqlite4ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iIneq, 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 SQLITE4_OMIT_OR_OPTIMIZATION
  if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
    /* Case 4:  Two or more separately indexed terms connected by OR
    **
    ** Example:
    **
    **   CREATE TABLE t1(a,b,c,d);
    **   CREATE INDEX i1 ON t1(a);
    **   CREATE INDEX i2 ON t1(b);
    **   CREATE INDEX i3 ON t1(c);
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
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891

3892
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
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
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
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
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
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
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
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
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
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
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
    **          Return     2                # Jump back to the Gosub
    **
    **       B: <after the loop>
    **
    */
    WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
    SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
    Index *pCov = 0;             /* Potential covering index (or NULL) */
    int iCovCur = pParse->nTab++;  /* Cursor used for index scans (if any) */

    int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
    int regKeyset = 0;                        /* Register for RowSet object */
    int regKey = 0;                           /* Register holding key */
    int iLoopBody = sqlite4VdbeMakeLabel(v);  /* Start of loop body */
    int iRetInit;                             /* Address of regReturn init */
    int untestedTerms = 0;             /* Some terms not completely tested */
    int ii;                            /* Loop counter */
    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
   
    pTerm = pLoop->aLTerm[0];
    assert( pTerm!=0 );
    assert( pTerm->eOperator & WO_OR );
    assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
    pOrWc = &pTerm->u.pOrInfo->wc;
    pLevel->op = OP_Return;
    pLevel->p1 = regReturn;

    /* Set up a new SrcList in pOrTab containing the table being scanned
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite4WhereBegin().
    */
    if( pWInfo->nLevel>1 ){
      int nNotReady;                 /* The number of notReady tables */
      struct SrcListItem *origSrc;     /* Original list of tables */
      nNotReady = pWInfo->nLevel - iLevel - 1;
      pOrTab = sqlite4StackAllocRaw(pParse->db,
                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
      if( pOrTab==0 ) return notReady;
      pOrTab->nAlloc = (u8)(nNotReady + 1);
      pOrTab->nSrc = pOrTab->nAlloc;
      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
      origSrc = pWInfo->pTabList->a;
      for(k=1; k<=nNotReady; k++){
        memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
      }
    }else{
      pOrTab = pWInfo->pTabList;
    }

    /* Initialize the keyset register to contain NULL. An SQL NULL is 
    ** equivalent to an empty keyset.
    **
    ** Also initialize regReturn to contain the address of the instruction 
    ** immediately following the OP_Return at the bottom of the loop. This
    ** is required in a few obscure LEFT JOIN cases where control jumps
    ** over the top of the loop into the body of it. In this case the 
    ** correct response for the end-of-loop code (the OP_Return) is to 
    ** fall through to the next instruction, just as an OP_Next does if
    ** called on an uninitialized cursor.
    */
    if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
      regKeyset = ++pParse->nMem;
      regKey = ++pParse->nMem;
      sqlite4VdbeAddOp2(v, OP_Null, 0, regKeyset);
    }
    iRetInit = sqlite4VdbeAddOp2(v, OP_Integer, 0, regReturn);

    /* If the original WHERE clause is z of the form:  (x1 OR x2 OR ...) AND y
    ** Then for every term xN, evaluate as the subexpression: xN AND z
    ** That way, terms in y that are factored into the disjunction will
    ** be picked up by the recursive calls to sqlite4WhereBegin() below.
    **
    ** Actually, each subexpression is converted to "xN AND w" where w is
    ** the "interesting" terms of z - terms that did not originate in the
    ** ON or USING clause of a LEFT JOIN, and terms that are usable as 
    ** indices.
    **
    ** This optimization also only applies if the (x1 OR x2 OR ...) term
    ** is not contained in the ON clause of a LEFT JOIN.
    ** See ticket http://www.sqlite.org/src/info/f2369304e4
    */
    if( pWC->nTerm>1 ){
      int iTerm;
      for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
        Expr *pExpr = pWC->a[iTerm].pExpr;
        if( &pWC->a[iTerm] == pTerm ) continue;
        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
        if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
        pExpr = sqlite4ExprDup(pParse->db, pExpr, 0);
        pAndExpr = sqlite4ExprAnd(pParse->db, pAndExpr, pExpr);
      }
      if( pAndExpr ){
        pAndExpr = sqlite4PExpr(pParse, TK_AND, 0, pAndExpr, 0);
      }
    }

    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
        WhereInfo *pSubWInfo;          /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr;
        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        pSubWInfo = sqlite4WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                        WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
        assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );
          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
            int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
            sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);

            sqlite4VdbeAddOp4Int(v, OP_RowSetTest, regKeyset,
                                 sqlite4VdbeCurrentAddr(v)+2, regKey, iSet);

          }
          sqlite4VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);

          /* The pSubWInfo->untestedTerms flag means that this OR term
          ** contained one or more AND term from a notReady table.  The
          ** terms from the notReady table could not be tested and will
          ** need to be tested later.
          */
          if( pSubWInfo->untestedTerms ) untestedTerms = 1;

          /* If all of the OR-connected terms are optimized using the same
          ** index, and the index is opened using the same cursor number
          ** by each call to sqlite4WhereBegin() made by this loop, it may
          ** be possible to use that index as a covering index.
          **
          ** If the call to sqlite4WhereBegin() above resulted in a scan that
          ** uses an index, and this is either the first OR-connected term
          ** processed or the index is the same as that used by all previous
          ** terms, set pCov to the candidate covering index. Otherwise, set 
          ** pCov to NULL to indicate that no candidate covering index will 
          ** be available.
          */
          pSubLoop = pSubWInfo->a[0].pWLoop;
          assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
          if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
           && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
          ){
            pCov = pSubLoop->u.btree.pIndex;
            assert( pCov->eIndexType==SQLITE4_INDEX_PRIMARYKEY 
                 || pSubWInfo->a[0].iIdxCur==iCovCur 
            );
          }else{
            pCov = 0;
          }

          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite4WhereEnd(pSubWInfo);
        }
      }
    }
    assert( pLevel->u.pCovidx==0 );
    if( pCov && pCov->eIndexType!=SQLITE4_INDEX_PRIMARYKEY ){
      pLevel->iIdxCur = iCovCur;
      pLevel->u.pCovidx = pCov;
    }
    if( pAndExpr ){
      pAndExpr->pLeft = 0;
      sqlite4ExprDelete(pParse->db, pAndExpr);
    }
    sqlite4VdbeChangeP1(v, iRetInit, sqlite4VdbeCurrentAddr(v));
    sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
    sqlite4VdbeResolveLabel(v, iLoopBody);

    if( pWInfo->nLevel>1 ) sqlite4StackFree(pParse->db, pOrTab);
    if( !untestedTerms ) disableTerm(pLevel, pTerm);
  }else
#endif /* SQLITE4_OMIT_OR_OPTIMIZATION */

  {
    /* Case 6:  There is no usable index.  We must do a complete
    **          scan of the entire table. This comes up when scanning
    **          through b-trees containing materialized sub-queries or 
    **          views.
    */
    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 = SQLITE4_STMTSTATUS_FULLSCAN_STEP;
  }
  newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.
  **
  ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
  ** the use of indices become tests that are evaluated against each row of
  ** the relevant input tables.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
    testcase( pTerm->wtFlags & TERM_CODED );
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->prereqAll & newNotReady)!=0 ){
      testcase( pWInfo->untestedTerms==0
               && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
      pWInfo->untestedTerms = 1;
      continue;
    }
    pE = pTerm->pExpr;
    assert( pE!=0 );
    if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
      continue;
    }
    sqlite4ExprIfFalse(pParse, pE, addrCont, SQLITE4_JUMPIFNULL);
    pTerm->wtFlags |= TERM_CODED;
  }

  /* Insert code to test for implied constraints based on transitivity
  ** of the "==" operator.
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    WhereTerm *pAlt;
    Expr sEq;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
    assert( !ExprHasProperty(pE, EP_FromJoin) );
    assert( (pTerm->prereqRight & newNotReady)!=0 );
    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
    if( pAlt==0 ) continue;
    if( pAlt->wtFlags & (TERM_CODED) ) continue;
    testcase( pAlt->eOperator & WO_EQ );
    testcase( pAlt->eOperator & WO_IN );
    VdbeNoopComment((v, "begin transitive constraint"));
    sEq = *pAlt->pExpr;
    sEq.pLeft = pE->pLeft;
    sqlite4ExprIfFalse(pParse, &sEq, addrCont, SQLITE4_JUMPIFNULL);
  }

  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.  
  */
  if( pLevel->iLeftJoin ){
    pLevel->addrFirst = sqlite4VdbeCurrentAddr(v);
    sqlite4VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
    VdbeComment((v, "record LEFT JOIN hit"));
    sqlite4ExprCacheClear(pParse);
    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
      testcase( pTerm->wtFlags & TERM_VIRTUAL );  /* IMP: R-30575-11662 */
      testcase( pTerm->wtFlags & TERM_CODED );
      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
      if( (pTerm->prereqAll & newNotReady)!=0 ){
        assert( pWInfo->untestedTerms );
        continue;
      }
      assert( pTerm->pExpr );
      sqlite4ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE4_JUMPIFNULL);
      pTerm->wtFlags |= TERM_CODED;
    }
  }
  sqlite4ReleaseTempReg(pParse, iReleaseReg);

  return newNotReady;
}

#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){
  int nb = 1+(pTabList->nSrc+7)/8;
  struct SrcListItem *pItem = pTabList->a + p->iTab;
  Table *pTab = pItem->pTab;
  sqlite4DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
                     p->iTab, nb, p->maskSelf, nb, p->prereq);
  sqlite4DebugPrintf(" %12s",
                     pItem->zAlias ? pItem->zAlias : pTab->zName);
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
    if( p->u.btree.pIndex ){
      const char *zName = p->u.btree.pIndex->zName;
      if( zName==0 ) zName = "ipk";
      if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
        int i = sqlite4Strlen30(zName) - 1;
        while( zName[i]!='_' ) i--;
        zName += i;
      }
      sqlite4DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq);
    }else{
      sqlite4DebugPrintf("%20s","");
    }
  }else{
    char *z;
    if( p->u.vtab.idxStr ){
      z = sqlite4_mprintf(0, "(%d,\"%s\",%x)",
                p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask);
    }else{
      z = sqlite4_mprintf(0, "(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
    }
    sqlite4DebugPrintf(" %-19s", z);
    sqlite4_free(0, z);
  }
  sqlite4DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm);
  sqlite4DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
}
#endif

/*
** Convert bulk memory into a valid WhereLoop that can be passed
** to whereLoopClear harmlessly.
*/
static void whereLoopInit(WhereLoop *p){
  p->aLTerm = p->aLTermSpace;
  p->nLTerm = 0;
  p->nLSlot = ArraySize(p->aLTermSpace);
  p->wsFlags = 0;
}

/*
** Clear the WhereLoop.u union.  Leave WhereLoop.pLTerm intact.
*/
static void whereLoopClearUnion(sqlite4 *db, WhereLoop *p){
  if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
    if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
#if 0
      sqlite4_free(p->u.vtab.idxStr);
#endif
      p->u.vtab.needFree = 0;
      p->u.vtab.idxStr = 0;
    }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
      sqlite4DbFree(db, p->u.btree.pIndex->zColAff);
      sqlite4DbFree(db, p->u.btree.pIndex);
      p->u.btree.pIndex = 0;
    }
  }
}

/*
** Deallocate internal memory used by a WhereLoop object
*/
static void whereLoopClear(sqlite4 *db, WhereLoop *p){
  if( p->aLTerm!=p->aLTermSpace ) sqlite4DbFree(db, p->aLTerm);
  whereLoopClearUnion(db, p);
  whereLoopInit(p);
}

/*
** Increase the memory allocation for pLoop->aLTerm[] to be at least n.
*/
static int whereLoopResize(sqlite4 *db, WhereLoop *p, int n){
  WhereTerm **paNew;
  if( p->nLSlot>=n ) return SQLITE4_OK;
  n = (n+7)&~7;
  paNew = sqlite4DbMallocRaw(db, sizeof(p->aLTerm[0])*n);
  if( paNew==0 ) return SQLITE4_NOMEM;
  memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
  if( p->aLTerm!=p->aLTermSpace ) sqlite4DbFree(db, p->aLTerm);
  p->aLTerm = paNew;
  p->nLSlot = n;
  return SQLITE4_OK;
}

/*
** Transfer content from the second pLoop into the first.
*/

static int whereLoopXfer(sqlite4 *db, WhereLoop *pTo, WhereLoop *pFrom){
  if( whereLoopResize(db, pTo, pFrom->nLTerm) ) return SQLITE4_NOMEM;
  whereLoopClearUnion(db, pTo);
  memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
  memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
  if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){
    pFrom->u.vtab.needFree = 0;
  }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){
    pFrom->u.btree.pIndex = 0;
  }
  return SQLITE4_OK;
}

/*
** Delete a WhereLoop object
*/
static void whereLoopDelete(sqlite4 *db, WhereLoop *p){
  whereLoopClear(db, p);
  sqlite4DbFree(db, p);
}

/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite4 *db, WhereInfo *pWInfo){
  if( ALWAYS(pWInfo) ){

    whereClauseClear(&pWInfo->sWC);
    while( pWInfo->pLoops ){







      WhereLoop *p = pWInfo->pLoops;
      pWInfo->pLoops = p->pNextLoop;



      whereLoopDelete(db, p);
    }



    sqlite4DbFree(db, pWInfo);
  }
}

/*
** Insert or replace a WhereLoop entry using the template supplied.
**
** An existing WhereLoop entry might be overwritten if the new template
** is better and has fewer dependencies.  Or the template will be ignored
** and no insert will occur if an existing WhereLoop is faster and has
** fewer dependencies than the template.  Otherwise a new WhereLoop is
** added based on the template.
**
** If pBuilder->pOrSet is not NULL then we only care about only the
** prerequisites and rRun and nOut costs of the N best loops.  That
** information is gathered in the pBuilder->pOrSet object.  This special
** processing mode is used only for OR clause processing.
**
** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
** still might overwrite similar loops with the new template if the
** template is better.  Loops may be overwritten if the following 
** conditions are met:
**
**    (1)  They have the same iTab.
**    (2)  They have the same iSortIdx.
**    (3)  The template has same or fewer dependencies than the current loop
**    (4)  The template has the same or lower cost than the current loop
**    (5)  The template uses more terms of the same index but has no additional
**         dependencies          
*/
static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
  WhereLoop **ppPrev, *p, *pNext = 0;
  WhereInfo *pWInfo = pBuilder->pWInfo;
  sqlite4 *db = pWInfo->pParse->db;

  assert( pTemplate->u.btree.pIndex || !(pTemplate->wsFlags & WHERE_INDEXED) );

  /* If pBuilder->pOrSet is defined, then only keep track of the costs
  ** and prereqs.
  */
  if( pBuilder->pOrSet!=0 ){
#if WHERETRACE_ENABLED
    u16 n = pBuilder->pOrSet->n;
    int x =
#endif
    whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
                                    pTemplate->nOut);
#if WHERETRACE_ENABLED
    if( sqlite4WhereTrace & 0x8 ){

      sqlite4DebugPrintf(x?"   or-%d:  ":"   or-X:  ", n);
      whereLoopPrint(pTemplate, pWInfo->pTabList);
    }
#endif
    return SQLITE4_OK;
  }

  /* Search for an existing WhereLoop to overwrite, or which takes
  ** priority over pTemplate.
  */
  for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){
    if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
      /* If either the iTab or iSortIdx values for two WhereLoop are different
      ** then those WhereLoops need to be considered separately.  Neither is
      ** a candidate to replace the other. */
      continue;
    }
    /* In the current implementation, the rSetup value is either zero
    ** or the cost of building an automatic index (NlogN) and the NlogN
    ** is the same for compatible WhereLoops. */
    assert( p->rSetup==0 || pTemplate->rSetup==0 
                 || p->rSetup==pTemplate->rSetup );

    /* whereLoopAddBtree() always generates and inserts the automatic index
    ** case first.  Hence compatible candidate WhereLoops never have a larger
    ** rSetup. Call this SETUP-INVARIANT */
    assert( p->rSetup>=pTemplate->rSetup );

    if( (p->prereq & pTemplate->prereq)==p->prereq
     && p->rSetup<=pTemplate->rSetup
     && p->rRun<=pTemplate->rRun
    ){
      /* This branch taken when p is equal or better than pTemplate in 
      ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
      assert( p->rSetup==pTemplate->rSetup );
      if( p->nLTerm<pTemplate->nLTerm
       && (p->wsFlags & WHERE_INDEXED)!=0
       && (pTemplate->wsFlags & WHERE_INDEXED)!=0
       && p->u.btree.pIndex==pTemplate->u.btree.pIndex
       && p->prereq==pTemplate->prereq
      ){
        /* Overwrite an existing WhereLoop with an similar one that uses
        ** more terms of the index */
        pNext = p->pNextLoop;
        break;
      }else{
        /* pTemplate is not helpful.
        ** Return without changing or adding anything */
        goto whereLoopInsert_noop;
      }
    }
    if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
     && p->rRun>=pTemplate->rRun
     && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */
    ){
      /* Overwrite an existing WhereLoop with a better one: one that is
      ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
      ** and is no worse in any of those categories. */
      pNext = p->pNextLoop;
      break;
    }
  }

  /* If we reach this point it means that either p[] should be overwritten
  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
  ** WhereLoop and insert it.
  */
#if WHERETRACE_ENABLED
  if( sqlite4WhereTrace & 0x8 ){
    if( p!=0 ){
      sqlite4DebugPrintf("ins-del:  ");
      whereLoopPrint(p, pWInfo->pTabList);
    }
    sqlite4DebugPrintf("ins-new:  ");
    whereLoopPrint(pTemplate, pWInfo->pTabList);
  }
#endif
  if( p==0 ){
    p = sqlite4DbMallocRaw(db, sizeof(WhereLoop));
    if( p==0 ) return SQLITE4_NOMEM;
    whereLoopInit(p);
  }
  whereLoopXfer(db, p, pTemplate);
  p->pNextLoop = pNext;
  *ppPrev = p;
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
    Index *pIndex = p->u.btree.pIndex;
    if( pIndex && pIndex->tnum==0 ){
      p->u.btree.pIndex = 0;
    }
  }
  return SQLITE4_OK;

  /* Jump here if the insert is a no-op */
whereLoopInsert_noop:
#if WHERETRACE_ENABLED
  if( sqlite4WhereTrace & 0x8 ){
    sqlite4DebugPrintf("ins-noop: ");
    whereLoopPrint(pTemplate, pWInfo->pTabList);
  }
#endif
  return SQLITE4_OK;  
}


/*
** We have so far matched pBuilder->pNew->u.btree.nEq terms of the index pIndex.
** Try to match one more.
*/
static int whereLoopAddBtreeIndex(
  WhereLoopBuilder *pBuilder,     /* The WhereLoop factory */
  struct SrcListItem *pSrc,      /* FROM clause term being analyzed */
  Index *pProbe,                  /* An index on pSrc */
  WhereCost nInMul                /* log(Number of iterations due to IN) */
){
  WhereInfo *pWInfo = pBuilder->pWInfo;  /* WHERE analyse context */
  Parse *pParse = pWInfo->pParse;        /* Parsing context */
  sqlite4 *db = pParse->db;       /* Database connection malloc context */
  WhereLoop *pNew;                /* Template WhereLoop under construction */
  WhereTerm *pTerm;               /* A WhereTerm under consideration */
  int opMask;                     /* Valid operators for constraints */
  WhereScan scan;                 /* Iterator for WHERE terms */
  Bitmask saved_prereq;           /* Original value of pNew->prereq */
  u16 saved_nLTerm;               /* Original value of pNew->nLTerm */
  int saved_nEq;                  /* Original value of pNew->u.btree.nEq */
  u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
  WhereCost saved_nOut;           /* Original value of pNew->nOut */
  int iCol;                       /* Index of the column in the table */
  int rc = SQLITE4_OK;             /* Return code */
  WhereCost nRowEst;              /* Estimated index selectivity */
  WhereCost rLogSize;             /* Logarithm of table size */
  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */

  assert( pProbe->eIndexType==SQLITE4_INDEX_USER
       || pProbe->eIndexType==SQLITE4_INDEX_UNIQUE
       || pProbe->eIndexType==SQLITE4_INDEX_PRIMARYKEY
  );

  pNew = pBuilder->pNew;
  if( db->mallocFailed ) return SQLITE4_NOMEM;

  assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
  assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
  if( pNew->wsFlags & WHERE_BTM_LIMIT ){
    opMask = WO_LT|WO_LE;
  }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
    opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
  }else{
    opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
  }
  if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);

  if( pNew->u.btree.nEq < pProbe->nColumn ){
    iCol = pProbe->aiColumn[pNew->u.btree.nEq];
    nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
    if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
  }else if( pProbe->eIndexType!=SQLITE4_INDEX_PRIMARYKEY ){
    Index *pPk;
    pPk = sqlite4FindPrimaryKey(pProbe->pTable, 0);
    iCol = idxColumnNumber(pProbe, pPk, pNew->u.btree.nEq);
    nRowEst = 0;
  }else{
    return SQLITE4_OK;
  }
  assert( iCol>=-1 );
  pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
                        opMask, pProbe);
  saved_nEq = pNew->u.btree.nEq;
  saved_nLTerm = pNew->nLTerm;
  saved_wsFlags = pNew->wsFlags;
  saved_prereq = pNew->prereq;
  saved_nOut = pNew->nOut;
  pNew->rSetup = 0;
  rLogSize = estLog(whereCost(pProbe->aiRowEst[0]));
  for(; rc==SQLITE4_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    int nIn = 0;
    if( pTerm->prereqRight & pNew->maskSelf ) continue;
#ifdef SQLITE4_ENABLE_STAT3
    if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){
      continue; /* skip IS NOT NULL constraints on a NOT NULL column */
    }
#endif
    pNew->wsFlags = saved_wsFlags;
    pNew->u.btree.nEq = saved_nEq;
    pNew->nLTerm = saved_nLTerm;
    if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
    pNew->aLTerm[pNew->nLTerm++] = pTerm;
    pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
    pNew->rRun = rLogSize; /* Baseline cost is log2(N).  Adjustments below */
    if( pTerm->eOperator & WO_IN ){
      Expr *pExpr = pTerm->pExpr;
      pNew->wsFlags |= WHERE_COLUMN_IN;
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* "x IN (SELECT ...)":  TUNING: the SELECT returns 25 rows */
        nIn = 46;  assert( 46==whereCost(25) );
      }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
        /* "x IN (value, value, ...)" */
        nIn = whereCost(pExpr->x.pList->nExpr);
      }
      pNew->rRun += nIn;
      pNew->u.btree.nEq++;
      pNew->nOut = nRowEst + nInMul + nIn;
    }else if( pTerm->eOperator & (WO_EQ) ){
      assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0
                  || nInMul==0 );
      pNew->wsFlags |= WHERE_COLUMN_EQ;
      if( iCol<0  
       || (pProbe->onError!=OE_None && nInMul==0
           && pNew->u.btree.nEq==pProbe->nColumn-1)
      ){
        assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
        pNew->wsFlags |= WHERE_ONEROW;
      }
      pNew->u.btree.nEq++;
      pNew->nOut = nRowEst + nInMul;
    }else if( pTerm->eOperator & (WO_ISNULL) ){
      pNew->wsFlags |= WHERE_COLUMN_NULL;
      pNew->u.btree.nEq++;
      /* TUNING: IS NULL selects 2 rows */
      nIn = 10;  assert( 10==whereCost(2) );
      pNew->nOut = nRowEst + nInMul + nIn;
    }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
      testcase( pTerm->eOperator & WO_GT );
      testcase( pTerm->eOperator & WO_GE );
      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
      pBtm = pTerm;
      pTop = 0;
    }else{
      assert( pTerm->eOperator & (WO_LT|WO_LE) );
      testcase( pTerm->eOperator & WO_LT );
      testcase( pTerm->eOperator & WO_LE );
      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
      pTop = pTerm;
      pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
                     pNew->aLTerm[pNew->nLTerm-2] : 0;
    }
    if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
      /* Adjust nOut and rRun for STAT3 range values */
      WhereCost rDiv;
      whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq,
                        pBtm, pTop, &rDiv);
      pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10;
    }
#ifdef SQLITE4_ENABLE_STAT3
    if( pNew->u.btree.nEq==1 && pProbe->nSample
     &&  OptimizationEnabled(db, SQLITE4_Stat3) ){
      tRowcnt nOut = 0;
      if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
        testcase( pTerm->eOperator & WO_EQ );
        testcase( pTerm->eOperator & WO_ISNULL );
        rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
      }else if( (pTerm->eOperator & WO_IN)
             &&  !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)  ){
        rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
      }
      if( rc==SQLITE4_OK ) pNew->nOut = whereCost(nOut);
    }
#endif
    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_PRIMARY_KEY))==0 ){
      /* Each row involves a step of the index, then a binary search of
      ** the main table */
      pNew->rRun =  whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10);
    }
    /* Step cost for each output row */
    pNew->rRun = whereCostAdd(pNew->rRun, pNew->nOut);
    /* TBD: Adjust nOut for additional constraints */
    rc = whereLoopInsert(pBuilder, pNew);
    if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
     && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0))
    ){
      whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
    }
  }
  pNew->prereq = saved_prereq;
  pNew->u.btree.nEq = saved_nEq;
  pNew->wsFlags = saved_wsFlags;
  pNew->nOut = saved_nOut;
  pNew->nLTerm = saved_nLTerm;
  return rc;
}

/*
** Return True if it is possible that pIndex might be useful in
** implementing the ORDER BY clause in pBuilder.
**
** Return False if pBuilder does not contain an ORDER BY clause or
** if there is no way for pIndex to be useful in implementing that
** ORDER BY clause.
*/
static int indexMightHelpWithOrderBy(
  WhereLoopBuilder *pBuilder,
  Index *pIndex,
  int iCursor
){
  ExprList *pOB;
  int ii, jj;

  if( pIndex->bUnordered ) return 0;
  if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
  for(ii=0; ii<pOB->nExpr; ii++){
    Expr *pExpr = sqlite4ExprSkipCollate(pOB->a[ii].pExpr);
    if( pExpr->op!=TK_COLUMN ) return 0;
    if( pExpr->iTable==iCursor ){
      for(jj=0; jj<pIndex->nColumn; jj++){
        if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
      }
    }
  }
  return 0;
}

/*
** Return a bitmask where 1s indicate that the corresponding column of
** the table is used by an index.  Only the first 63 columns are considered.
*/
static Bitmask columnsInIndex(Index *pIdx){
  Bitmask m = 0;
  if( pIdx->eIndexType!=SQLITE4_INDEX_PRIMARYKEY ){
    int j;
    for(j=pIdx->nCover-1; j>=0; j--){
      int x = pIdx->aiCover[j];
      testcase( x==BMS-1 );
      testcase( x==BMS-2 );
      if( x<BMS-1 ) m |= MASKBIT(x);
    }
  }
  return m;
}

static int whereLoopAddMatch(
  WhereLoopBuilder *pBuilder, 
  struct SrcListItem *pSrc,
  Bitmask mExtra, 
  int *pbDone
){
  WhereClause *pWC = pBuilder->pWC;
  int iTerm;
  int rc = SQLITE4_OK;
  if( findMatchExpr(pWC, pSrc, &iTerm) ){
    WhereLoop *pNew = pBuilder->pNew;

    pNew->prereq = pWC->a[iTerm].prereqRight; 
    pNew->wsFlags = WHERE_INDEXED;
    pNew->rSetup = 0;
    pNew->rRun = 1;
    pNew->nOut = 1;
    pNew->u.btree.nEq = 0;
    pNew->u.btree.pIndex = pWC->a[iTerm].pExpr->pIdx;
    
    rc = whereLoopInsert(pBuilder, pNew);
    *pbDone = 1;
  }else{
    *pbDone = 0;
  }
  return rc;
}

/*
** Add all WhereLoop objects for a single table of the join where the table
** is idenfied by pBuilder->pNew->iTab.  That table is guaranteed to be
** a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(
  WhereLoopBuilder *pBuilder, /* WHERE clause information */
  Bitmask mExtra              /* Extra prerequesites for using this table */
){
  WhereInfo *pWInfo;          /* WHERE analysis context */
  Index *pProbe;              /* An index we are evaluating */
  Index *pPk;                 /* Primary key index for table pSrc */
  SrcList *pTabList;          /* The FROM clause */
  struct SrcListItem *pSrc;   /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE4_OK;        /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  WhereCost rSize;            /* number of rows in the table */
  WhereCost rLogSize;         /* Logarithm of the number of rows in the table */
  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;
  assert( !IsVirtual(pSrc->pTab) );
  pPk = sqlite4FindPrimaryKey(pSrc->pTab, 0);

  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else if( pSrc->notIndexed ){
    /* A NOT INDEXED clause means use the PK index */
    pProbe = pPk;
  }else{
    /* Otherwise, consider all indexes */
    pProbe = pSrc->pTab->pIndex;
  }

  rc = whereLoopAddMatch(pBuilder, pSrc, mExtra, &b);
  if( b ) return rc;
  assert( rc==SQLITE4_OK );

  rSize = whereCost(pSrc->pTab->nRowEst);
  rLogSize = estLog(rSize);

#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
   && (pWInfo->pParse->db->flags & SQLITE4_AutoIndex)!=0
   && pSrc->pIndex==0
#if 0
   && !pSrc->viaCoroutine
#endif
   && !pSrc->notIndexed
   && !pSrc->isCorrelated
  ){
    /* Generate auto-index WhereLoops */
    WhereClause *pWC = pBuilder->pWC;
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE4_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->u.btree.pIndex = 0;
        pNew->nLTerm = 1;
        pNew->aLTerm[0] = pTerm;
        /* TUNING: One-time cost for computing the automatic index is
        ** approximately 7*N*log2(N) where N is the number of rows in
        ** the table being indexed. */
        pNew->rSetup = rLogSize + rSize + 28;  assert( 28==whereCost(7) );
        /* TUNING: Each index lookup yields 20 rows in the table.  This
        ** is more than the usual guess of 10 rows, since we have no way
        ** of knowning how selective the index will ultimately be.  It would
        ** not be unreasonable to make this value much larger. */
        pNew->nOut = 43;  assert( 43==whereCost(20) );
        pNew->rRun = whereCostAdd(rLogSize,pNew->nOut);
        pNew->wsFlags = WHERE_AUTO_INDEX;
        pNew->prereq = mExtra | pTerm->prereqRight;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }
#endif /* ifndef SQLITE4_OMIT_AUTOMATIC_INDEX */

  /* If this table has no primary key, then it is either a materialized
  ** view or ephemeral table. Either way, add a WhereLoop for a full-scan 
  ** of it.  */
  if( pPk==0 ){
    assert( pSrc->pTab->pSelect || (pSrc->pTab->tabFlags & TF_Ephemeral) );
    pNew->u.btree.nEq = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = 0;
    pNew->wsFlags = 0;
    pNew->rRun = whereCostAdd(rSize,rLogSize) + 16;
    rc = whereLoopInsert(pBuilder, pNew);
  }

  /* Loop through the set of indices being considered. */
  for(; rc==SQLITE4_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
    int bCover = (pProbe!=pPk && 0==(pSrc->colUsed & ~columnsInIndex(pProbe)));
    if( pProbe->eIndexType==SQLITE4_INDEX_FTS5 ) continue;
    assert( pProbe->tnum>0 );

    pNew->u.btree.nEq = 0;
    pNew->nLTerm = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
    pNew->wsFlags = WHERE_INDEXED;
    pNew->wsFlags |= (bCover ? WHERE_IDX_ONLY : 0); 
    pNew->wsFlags |= (pProbe==pPk ? WHERE_PRIMARY_KEY : 0);

    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
    /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
    assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
    pNew->iSortIdx = b ? iSortIdx : 0;

    if( pProbe==pPk || b || (bCover
     && pProbe->bUnordered==0
     && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
#if 0
     && sqlite4GlobalConfig.bUseCis
     && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
#endif
    )){
      if( pProbe==pPk ){
        /* TUNING: Cost of full table scan is 3*(N + log2(N)).
        **  +  The extra 3 factor is to encourage the use of indexed lookups
        **     over full scans.  A smaller constant 2 is used for covering
        **     index scans so that a covering index scan will be favored over
        **     a table scan. */
        pNew->rRun = whereCostAdd(rSize,rLogSize) + 16;
      }else if( bCover ){
        /* TUNING: Cost of a covering index scan is 2*(N + log2(N)).
        **  +  The extra 2 factor is to encourage the use of indexed lookups
        **     over index scans.  A table scan uses a factor of 3 so that
        **     index scans are favored over table scans.
        **  +  If this covering index might also help satisfy the ORDER BY
        **     clause, then the cost is fudged down slightly so that this
        **     index is favored above other indices that have no hope of
        **     helping with the ORDER BY. */
        pNew->rRun = 10 + whereCostAdd(rSize,rLogSize) - b;
      }else{
        assert( b!=0 ); 
        /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
         ** which we will simplify to just N*log2(N) */
        pNew->rRun = rSize + rLogSize;
      }
      rc = whereLoopInsert(pBuilder, pNew);
      if( rc ) break;
    }

    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);

    /* If there was an INDEXED BY or NOT INDEXED clause, then only one
    ** index is considered. */
    if( pSrc->pIndex || pSrc->notIndexed ) break;
  }
  return rc;
}

#ifndef SQLITE4_OMIT_VIRTUALTABLE
/*
** Add all WhereLoop objects for a table of the join identified by
** pBuilder->pNew->iTab.  That table is guaranteed to be a virtual table.
*/
static int whereLoopAddVirtual(
  WhereLoopBuilder *pBuilder   /* WHERE clause information */
){
  WhereInfo *pWInfo;           /* WHERE analysis context */
  Parse *pParse;               /* The parsing context */
  WhereClause *pWC;            /* The WHERE clause */
  struct SrcListItem *pSrc;   /* The FROM clause term to search */
  Table *pTab;
  sqlite4 *db;
  sqlite4_index_info *pIdxInfo;
  struct sqlite4_index_constraint *pIdxCons;
  struct sqlite4_index_constraint_usage *pUsage;
  WhereTerm *pTerm;
  int i, j;
  int iTerm, mxTerm;
  int nConstraint;
  int seenIn = 0;              /* True if an IN operator is seen */
  int seenVar = 0;             /* True if a non-constant constraint is seen */
  int iPhase;                  /* 0: const w/o IN, 1: const, 2: no IN,  2: IN */
  WhereLoop *pNew;
  int rc = SQLITE4_OK;

  pWInfo = pBuilder->pWInfo;
  pParse = pWInfo->pParse;
  db = pParse->db;
  pWC = pBuilder->pWC;
  pNew = pBuilder->pNew;
  pSrc = &pWInfo->pTabList->a[pNew->iTab];
  pTab = pSrc->pTab;
  assert( IsVirtual(pTab) );
  pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
  if( pIdxInfo==0 ) return SQLITE4_NOMEM;
  pNew->prereq = 0;
  pNew->rSetup = 0;
  pNew->wsFlags = WHERE_VIRTUALTABLE;
  pNew->nLTerm = 0;
  pNew->u.vtab.needFree = 0;
  pUsage = pIdxInfo->aConstraintUsage;
  nConstraint = pIdxInfo->nConstraint;
  if( whereLoopResize(db, pNew, nConstraint) ){
    sqlite4DbFree(db, pIdxInfo);
    return SQLITE4_NOMEM;
  }

  for(iPhase=0; iPhase<=3; iPhase++){
    if( !seenIn && (iPhase&1)!=0 ){
      iPhase++;
      if( iPhase>3 ) break;
    }
    if( !seenVar && iPhase>1 ) break;
    pIdxCons = *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint;
    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
      j = pIdxCons->iTermOffset;
      pTerm = &pWC->a[j];
      switch( iPhase ){
        case 0:    /* Constants without IN operator */
          pIdxCons->usable = 0;
          if( (pTerm->eOperator & WO_IN)!=0 ){
            seenIn = 1;
          }
          if( pTerm->prereqRight!=0 ){
            seenVar = 1;
          }else if( (pTerm->eOperator & WO_IN)==0 ){
            pIdxCons->usable = 1;
          }
          break;
        case 1:    /* Constants with IN operators */
          assert( seenIn );
          pIdxCons->usable = (pTerm->prereqRight==0);
          break;
        case 2:    /* Variables without IN */
          assert( seenVar );
          pIdxCons->usable = (pTerm->eOperator & WO_IN)==0;
          break;
        default:   /* Variables with IN */
          assert( seenVar && seenIn );
          pIdxCons->usable = 1;
          break;
      }
    }
    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
    if( pIdxInfo->needToFreeIdxStr ) sqlite4_free(pIdxInfo->idxStr);
    pIdxInfo->idxStr = 0;
    pIdxInfo->idxNum = 0;
    pIdxInfo->needToFreeIdxStr = 0;
    pIdxInfo->orderByConsumed = 0;
    pIdxInfo->estimatedCost = SQLITE4_BIG_DBL / (double)2;
    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
    if( rc ) goto whereLoopAddVtab_exit;
    pIdxCons = *(struct sqlite4_index_constraint**)&pIdxInfo->aConstraint;
    pNew->prereq = 0;
    mxTerm = -1;
    assert( pNew->nLSlot>=nConstraint );
    for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
    pNew->u.vtab.omitMask = 0;
    for(i=0; i<nConstraint; i++, pIdxCons++){
      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
        j = pIdxCons->iTermOffset;
        if( iTerm>=nConstraint
         || j<0
         || j>=pWC->nTerm
         || pNew->aLTerm[iTerm]!=0
        ){
          rc = SQLITE4_ERROR;
          sqlite4ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
          goto whereLoopAddVtab_exit;
        }
        testcase( iTerm==nConstraint-1 );
        testcase( j==0 );
        testcase( j==pWC->nTerm-1 );
        pTerm = &pWC->a[j];
        pNew->prereq |= pTerm->prereqRight;
        assert( iTerm<pNew->nLSlot );
        pNew->aLTerm[iTerm] = pTerm;
        if( iTerm>mxTerm ) mxTerm = iTerm;
        testcase( iTerm==15 );
        testcase( iTerm==16 );
        if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
        if( (pTerm->eOperator & WO_IN)!=0 ){
          if( pUsage[i].omit==0 ){
            /* Do not attempt to use an IN constraint if the virtual table
            ** says that the equivalent EQ constraint cannot be safely omitted.
            ** If we do attempt to use such a constraint, some rows might be
            ** repeated in the output. */
            break;
          }
          /* A virtual table that is constrained by an IN clause may not
          ** consume the ORDER BY clause because (1) the order of IN terms
          ** is not necessarily related to the order of output terms and
          ** (2) Multiple outputs from a single IN value will not merge
          ** together.  */
          pIdxInfo->orderByConsumed = 0;
        }
      }
    }
    if( i>=nConstraint ){
      pNew->nLTerm = mxTerm+1;
      assert( pNew->nLTerm<=pNew->nLSlot );
      pNew->u.vtab.idxNum = pIdxInfo->idxNum;
      pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
      pIdxInfo->needToFreeIdxStr = 0;
      pNew->u.vtab.idxStr = pIdxInfo->idxStr;
      pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0)
                                     && pIdxInfo->orderByConsumed);
      pNew->rSetup = 0;
      pNew->rRun = whereCostFromDouble(pIdxInfo->estimatedCost);
      /* TUNING: Every virtual table query returns 25 rows */
      pNew->nOut = 46;  assert( 46==whereCost(25) );
      whereLoopInsert(pBuilder, pNew);
      if( pNew->u.vtab.needFree ){
        sqlite4_free(pNew->u.vtab.idxStr);
        pNew->u.vtab.needFree = 0;
      }
    }
  }  

whereLoopAddVtab_exit:
  if( pIdxInfo->needToFreeIdxStr ) sqlite4_free(pIdxInfo->idxStr);
  sqlite4DbFree(db, pIdxInfo);
  return rc;
}
#endif /* SQLITE4_OMIT_VIRTUALTABLE */

/*
** Add WhereLoop entries to handle OR terms.  This works for either
** btrees or virtual tables.
*/
static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
  WhereInfo *pWInfo = pBuilder->pWInfo;
  WhereClause *pWC;
  WhereLoop *pNew;
  WhereTerm *pTerm, *pWCEnd;
  int rc = SQLITE4_OK;
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur, sPrev;
  struct SrcListItem *pItem;
  
  pWC = pBuilder->pWC;
  if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE4_OK;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE4_OK; pTerm++){
    if( (pTerm->eOperator & WO_OR)!=0
     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
      WhereTerm *pOrTerm;
      int once = 1;
      int i, j;
    
      pItem = pWInfo->pTabList->a + pNew->iTab;
      iCur = pItem->iCursor;
      sSubBuild = *pBuilder;
      sSubBuild.pOrderBy = 0;
      sSubBuild.pOrSet = &sCur;

      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        if( (pOrTerm->eOperator & WO_AND)!=0 ){
          sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
        }else if( pOrTerm->leftCursor==iCur ){
          tempWC.pWInfo = pWC->pWInfo;
          tempWC.pOuter = pWC;
          tempWC.op = TK_AND;
          tempWC.nTerm = 1;
          tempWC.a = pOrTerm;
          sSubBuild.pWC = &tempWC;
        }else{
          continue;
        }
        sCur.n = 0;
#ifndef SQLITE4_OMIT_VIRTUALTABLE
        if( IsVirtual(pItem->pTab) ){
          rc = whereLoopAddVirtual(&sSubBuild);
          for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra;
        }else
#endif
        {
          rc = whereLoopAddBtree(&sSubBuild, mExtra);
        }
        assert( rc==SQLITE4_OK || sCur.n==0 );
        if( sCur.n==0 ){
          sSum.n = 0;
          break;
        }else if( once ){
          whereOrMove(&sSum, &sCur);
          once = 0;
        }else{
          whereOrMove(&sPrev, &sSum);
          sSum.n = 0;
          for(i=0; i<sPrev.n; i++){
            for(j=0; j<sCur.n; j++){
              whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq,
                            whereCostAdd(sPrev.a[i].rRun, sCur.a[j].rRun),
                            whereCostAdd(sPrev.a[i].nOut, sCur.a[j].nOut));
            }
          }
        }
      }
      pNew->nLTerm = 1;
      pNew->aLTerm[0] = pTerm;
      pNew->wsFlags = WHERE_MULTI_OR;
      pNew->rSetup = 0;
      pNew->iSortIdx = 0;
      memset(&pNew->u, 0, sizeof(pNew->u));
      for(i=0; rc==SQLITE4_OK && i<sSum.n; i++){
        /* TUNING: Multiple by 3.5 for the secondary table lookup */
        pNew->rRun = sSum.a[i].rRun + 18;
        pNew->nOut = sSum.a[i].nOut;
        pNew->prereq = sSum.a[i].prereq;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }
  return rc;
}

/*
** Add all WhereLoop objects for all tables 
*/
static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
  WhereInfo *pWInfo = pBuilder->pWInfo;
  Bitmask mExtra = 0;
  Bitmask mPrior = 0;
  int iTab;
  SrcList *pTabList = pWInfo->pTabList;
  struct SrcListItem *pItem;
  sqlite4 *db = pWInfo->pParse->db;
  int nTabList = pWInfo->nLevel;
  int rc = SQLITE4_OK;
  u8 priorJoinType = 0;
  WhereLoop *pNew;

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);
  for(iTab=0, pItem=pTabList->a; iTab<nTabList; iTab++, pItem++){
    pNew->iTab = iTab;
    pNew->maskSelf = getMask(&pWInfo->sMaskSet, pItem->iCursor);
    if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
      mExtra = mPrior;
    }
    priorJoinType = pItem->jointype;
#ifndef SQLITE4_OMIT_VIRTUALTABLE
    if( IsVirtual(pItem->pTab) ){
      rc = whereLoopAddVirtual(pBuilder);
    }else
#endif
    {
      rc = whereLoopAddBtree(pBuilder, mExtra);
    }
    if( rc==SQLITE4_OK ){
      rc = whereLoopAddOr(pBuilder, mExtra);
    }
    mPrior |= pNew->maskSelf;
    if( rc || db->mallocFailed ) break;
  }
  whereLoopClear(db, pNew);
  return rc;
}

/*
** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
** parameters) to see if it outputs rows in the requested ORDER BY
** (or GROUP BY) without requiring a separate sort operation.  Return:
** 
**    0:  ORDER BY is not satisfied.  Sorting required
**    1:  ORDER BY is satisfied.      Omit sorting
**   -1:  Unknown at this time
**
** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as
** strict.  With GROUP BY and DISTINCT the only requirement is that
** equivalent rows appear immediately adjacent to one another.  GROUP BY
** and DISTINT do not require rows to appear in any particular order as long
** as equivelent rows are grouped together.  Thus for GROUP BY and DISTINCT
** the pOrderBy terms can be matched in any order.  With ORDER BY, the 
** pOrderBy terms must be matched in strict left-to-right order.
*/
static int wherePathSatisfiesOrderBy(
  WhereInfo *pWInfo,    /* The WHERE clause */
  ExprList *pOrderBy,   /* ORDER BY or GROUP BY or DISTINCT clause to check */
  WherePath *pPath,     /* The WherePath to check */
  u16 wctrlFlags,       /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
  u16 nLoop,            /* Number of entries in pPath->aLoop[] */
  WhereLoop *pLast,     /* Add this WhereLoop to the end of pPath->aLoop[] */
  Bitmask *pRevMask     /* OUT: Mask of WhereLoops to run in reverse order */
){
  u8 revSet;            /* True if rev is known */
  u8 rev;               /* Composite sort order */
  u8 revIdx;            /* Index sort order */
  u8 isOrderDistinct;   /* All prior WhereLoops are order-distinct */
  u8 isMatch;           /* iColumn matches a term of the ORDER BY clause */
  u16 nColumn;          /* Number of columns in pIndex */
  u16 nOrderBy;         /* Number terms in the ORDER BY clause */
  int iLoop;            /* Index of WhereLoop in pPath being processed */
  int i, j;             /* Loop counters */
  int iCur;             /* Cursor number for current WhereLoop */
  int iColumn;          /* A column number within table iCur */
  WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */
  WhereTerm *pTerm;     /* A single term of the WHERE clause */
  Expr *pOBExpr;        /* An expression from the ORDER BY clause */
  CollSeq *pColl;       /* COLLATE function from an ORDER BY clause term */
  Index *pIndex;        /* The index associated with pLoop */
  sqlite4 *db = pWInfo->pParse->db;  /* Database connection */
  Bitmask obSat = 0;    /* Mask of ORDER BY terms satisfied so far */
  Bitmask obDone;       /* Mask of all ORDER BY terms */
  Bitmask orderDistinctMask;  /* Mask of all well-ordered loops */
  Bitmask ready;              /* Mask of inner loops */

  /*
  ** We say the WhereLoop is "one-row" if it generates no more than one
  ** row of output.  A WhereLoop is one-row if all of the following are true:
  **  (a) All index columns match with WHERE_COLUMN_EQ.
  **  (b) The index is unique
  ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row.
  ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags.
  **
  ** We say the WhereLoop is "order-distinct" if the set of columns from
  ** that WhereLoop that are in the ORDER BY clause are different for every
  ** row of the WhereLoop.  Every one-row WhereLoop is automatically
  ** order-distinct.   A WhereLoop that has no columns in the ORDER BY clause
  ** is not order-distinct. To be order-distinct is not quite the same as being
  ** UNIQUE since a UNIQUE column or index can have multiple rows that 
  ** are NULL and NULL values are equivalent for the purpose of order-distinct.
  ** To be order-distinct, the columns must be UNIQUE and NOT NULL.
  **
  ** The rowid for a table is always UNIQUE and NOT NULL so whenever the
  ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is
  ** automatically order-distinct.
  */

  assert( pOrderBy!=0 );

  /* Sortability of virtual tables is determined by the xBestIndex method
  ** of the virtual table itself */
  if( pLast->wsFlags & WHERE_VIRTUALTABLE ){
    testcase( nLoop>0 );  /* True when outer loops are one-row and match 
                          ** no ORDER BY terms */
    return pLast->u.vtab.isOrdered;
  }
  if( nLoop && OptimizationDisabled(db, SQLITE4_OrderByIdxJoin) ) return 0;

  nOrderBy = pOrderBy->nExpr;
  testcase( nOrderBy==BMS-1 );
  if( nOrderBy>BMS-1 ) return 0;  /* Cannot optimize overly large ORDER BYs */
  isOrderDistinct = 1;
  obDone = MASKBIT(nOrderBy)-1;
  orderDistinctMask = 0;
  ready = 0;
  for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
    if( iLoop>0 ) ready |= pLoop->maskSelf;
    pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast;
    assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
    iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;

    /* Mark off any ORDER BY term X that is a column in the table of
    ** the current loop for which there is term in the WHERE
    ** clause of the form X IS NULL or X=? that reference only outer
    ** loops.
    */
    for(i=0; i<nOrderBy; i++){
      if( MASKBIT(i) & obSat ) continue;
      pOBExpr = sqlite4ExprSkipCollate(pOrderBy->a[i].pExpr);
      if( pOBExpr->op!=TK_COLUMN ) continue;
      if( pOBExpr->iTable!=iCur ) continue;
      pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
                       ~ready, WO_EQ|WO_ISNULL, 0);
      if( pTerm==0 ) continue;
      if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
        const char *z1, *z2;
        pColl = sqlite4ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
        if( !pColl ) pColl = db->pDfltColl;
        z1 = pColl->zName;
        pColl = sqlite4ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
        if( !pColl ) pColl = db->pDfltColl;
        z2 = pColl->zName;
        if( sqlite4_stricmp(z1, z2)!=0 ) continue;
      }
      obSat |= MASKBIT(i);
    }

    if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
      Index *pPk = 0;
      if( (pIndex = pLoop->u.btree.pIndex)==0 
        || pIndex->bUnordered 
        || pIndex->eIndexType==SQLITE4_INDEX_FTS5 
      ){
        return 0;
      }else{
        isOrderDistinct = pIndex->onError!=OE_None;
        pPk = sqlite4FindPrimaryKey(pIndex->pTable, 0);
        nColumn = idxColumnCount(pIndex, pPk);
      }

      /* Loop through all columns of the index and deal with the ones
      ** that are not constrained by == or IN.
      */
      rev = revSet = 0;
      for(j=0; j<nColumn; j++){
        u8 bOnce;   /* True to run the ORDER BY search loop */

        /* Skip over == and IS NULL terms */
        if( j<pLoop->u.btree.nEq
         && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
        ){
          if( i & WO_ISNULL ){
            testcase( isOrderDistinct );
            isOrderDistinct = 0;
          }
          continue;  
        }

        /* Get the column number in the table (iColumn) and sort order
        ** (revIdx) for the j-th column of the index.
        */
        if( j<nColumn ){
          /* Normal index columns */
          iColumn = idxColumnNumber(pIndex, pPk, j);
          revIdx = idxColumnSortOrder(pIndex, pPk, j);
        }else{
          /* The ROWID column at the end */
          assert( j==nColumn );
          iColumn = -1;
          revIdx = 0;
        }

        /* An unconstrained column that might be NULL means that this
        ** WhereLoop is not well-ordered 
        */
        if( isOrderDistinct
         && iColumn>=0
         && j>=pLoop->u.btree.nEq
         && pIndex->pTable->aCol[iColumn].notNull==0
        ){
          isOrderDistinct = 0;
        }

        /* Find the ORDER BY term that corresponds to the j-th column
        ** of the index and and mark that ORDER BY term off 
        */
        bOnce = 1;
        isMatch = 0;
        for(i=0; bOnce && i<nOrderBy; i++){
          if( MASKBIT(i) & obSat ) continue;
          pOBExpr = sqlite4ExprSkipCollate(pOrderBy->a[i].pExpr);
          testcase( wctrlFlags & WHERE_GROUPBY );
          testcase( wctrlFlags & WHERE_DISTINCTBY );
          if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
          if( pOBExpr->op!=TK_COLUMN ) continue;
          if( pOBExpr->iTable!=iCur ) continue;
          if( pOBExpr->iColumn!=iColumn ) continue;
          if( iColumn>=0 ){
            const char *zIdxColl;
            pColl = sqlite4ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
            if( !pColl ) pColl = db->pDfltColl;
            zIdxColl = idxColumnCollation(pIndex, pPk, j);
            if( sqlite4_stricmp(pColl->zName, zIdxColl)!=0 ) continue;
          }
          isMatch = 1;
          break;
        }
        if( isMatch ){
          obSat |= MASKBIT(i);
          if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
            /* Make sure the sort order is compatible in an ORDER BY clause.
            ** Sort order is irrelevant for a GROUP BY clause. */
            if( revSet ){
              if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) return 0;
            }else{
              rev = revIdx ^ pOrderBy->a[i].sortOrder;
              if( rev ) *pRevMask |= MASKBIT(iLoop);
              revSet = 1;
            }
          }
        }else{
          /* No match found */
          if( j==0 || j<nColumn ){
            testcase( isOrderDistinct!=0 );
            isOrderDistinct = 0;
          }
          break;
        }
      } /* end Loop over all index columns */

      /* If (j==nColumn), then each column of the index, including any 
      ** appended PK columns, corresponds to either an ORDER BY term or 
      ** equality constraint. Since the PK columns are collectively UNIQUE
      ** and NOT NULL, consider the loop order-distinct.  */
      if( j==nColumn ){
        testcase( isOrderDistinct==0 );
        isOrderDistinct = 1;
      }
    } /* end-if not one-row */

    /* Mark off any other ORDER BY terms that reference pLoop */
    if( isOrderDistinct ){
      orderDistinctMask |= pLoop->maskSelf;
      for(i=0; i<nOrderBy; i++){
        Expr *p;
        if( MASKBIT(i) & obSat ) continue;
        p = pOrderBy->a[i].pExpr;
        if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
          obSat |= MASKBIT(i);
        }
      }
    }
  } /* End the loop over all WhereLoops from outer-most down to inner-most */
  if( obSat==obDone ) return 1;
  if( !isOrderDistinct ) return 0;
  return -1;
}

#ifdef WHERETRACE_ENABLED
/* For debugging use only: */
static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
  static char zName[65];
  int i;
  for(i=0; i<nLoop; i++){ zName[i] = pPath->aLoop[i]->cId; }
  if( pLast ) zName[i++] = pLast->cId;
  zName[i] = 0;
  return zName;
}
#endif


/*
** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
** attempts to find the lowest cost path that visits each WhereLoop
** once.  This path is then loaded into the pWInfo->a[].pWLoop fields.
**
** Assume that the total number of output rows that will need to be sorted
** will be nRowEst (in the 10*log2 representation).  Or, ignore sorting
** costs if nRowEst==0.
**
** Return SQLITE4_OK on success or SQLITE4_NOMEM of a memory allocation
** error occurs.
*/
static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
  int mxChoice;             /* Maximum number of simultaneous paths tracked */
  int nLoop;                /* Number of terms in the join */
  Parse *pParse;            /* Parsing context */
  sqlite4 *db;              /* The database connection */
  int iLoop;                /* Loop counter over the terms of the join */
  int ii, jj;               /* Loop counters */
  WhereCost rCost;             /* Cost of a path */
  WhereCost mxCost = 0;        /* Maximum cost of a set of paths */
  WhereCost rSortCost;         /* Cost to do a sort */
  int nTo, nFrom;           /* Number of valid entries in aTo[] and aFrom[] */
  WherePath *aFrom;         /* All nFrom paths at the previous level */
  WherePath *aTo;           /* The nTo best paths at the current level */
  WherePath *pFrom;         /* An element of aFrom[] that we are working on */
  WherePath *pTo;           /* An element of aTo[] that we are working on */
  WhereLoop *pWLoop;        /* One of the WhereLoop objects */
  WhereLoop **pX;           /* Used to divy up the pSpace memory */
  char *pSpace;             /* Temporary memory used by this routine */

  pParse = pWInfo->pParse;
  db = pParse->db;
  nLoop = pWInfo->nLevel;
  /* TUNING: For simple queries, only the best path is tracked.
  ** For 2-way joins, the 5 best paths are followed.
  ** For joins of 3 or more tables, track the 10 best paths */
  mxChoice = (nLoop==1) ? 1 : (nLoop==2 ? 5 : 10);
  assert( nLoop<=pWInfo->pTabList->nSrc );
  WHERETRACE(0x002, ("---- begin solver\n"));

  /* Allocate and initialize space for aTo and aFrom */
  ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
  pSpace = sqlite4DbMallocRaw(db, ii);
  if( pSpace==0 ) return SQLITE4_NOMEM;
  aTo = (WherePath*)pSpace;
  aFrom = aTo+mxChoice;
  memset(aFrom, 0, sizeof(aFrom[0]));
  pX = (WhereLoop**)(aFrom+mxChoice);
  for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
    pFrom->aLoop = pX;
  }

  /* Seed the search with a single WherePath containing zero WhereLoops.
  **
  ** TUNING: Do not let the number of iterations go above 25.  If the cost
  ** of computing an automatic index is not paid back within the first 25
  ** rows, then do not use the automatic index. */
  aFrom[0].nRow = MIN(pParse->nQueryLoop, 46);  assert( 46==whereCost(25) );
  nFrom = 1;

  /* Precompute the cost of sorting the final result set, if the caller
  ** to sqlite4WhereBegin() was concerned about sorting */
  rSortCost = 0;
  if( pWInfo->pOrderBy==0 || nRowEst==0 ){
    aFrom[0].isOrderedValid = 1;
  }else{
    /* TUNING: Estimated cost of sorting is N*log2(N) where N is the
    ** number of output rows. */
    rSortCost = nRowEst + estLog(nRowEst);
    WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost));
  }

  /* Compute successively longer WherePaths using the previous generation
  ** of WherePaths as the basis for the next.  Keep track of the mxChoice
  ** best paths at each generation */
  for(iLoop=0; iLoop<nLoop; iLoop++){
    nTo = 0;
    for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
      for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
        Bitmask maskNew;
        Bitmask revMask = 0;
        u8 isOrderedValid = pFrom->isOrderedValid;
        u8 isOrdered = pFrom->isOrdered;
        if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
        if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
        /* At this point, pWLoop is a candidate to be the next loop. 
        ** Compute its cost */
        rCost = whereCostAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
        rCost = whereCostAdd(rCost, pFrom->rCost);
        maskNew = pFrom->maskLoop | pWLoop->maskSelf;
        if( !isOrderedValid ){
          switch( wherePathSatisfiesOrderBy(pWInfo,
                       pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
                       iLoop, pWLoop, &revMask) ){
            case 1:  /* Yes.  pFrom+pWLoop does satisfy the ORDER BY clause */
              isOrdered = 1;
              isOrderedValid = 1;
              break;
            case 0:  /* No.  pFrom+pWLoop will require a separate sort */
              isOrdered = 0;
              isOrderedValid = 1;
              rCost = whereCostAdd(rCost, rSortCost);
              break;
            default: /* Cannot tell yet.  Try again on the next iteration */
              break;
          }
        }else{
          revMask = pFrom->revLoop;
        }
        /* Check to see if pWLoop should be added to the mxChoice best so far */
        for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
          if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
            testcase( jj==nTo-1 );
            break;
          }
        }
        if( jj>=nTo ){
          if( nTo>=mxChoice && rCost>=mxCost ){
#ifdef WHERETRACE_ENABLED
            if( sqlite4WhereTrace&0x4 ){
              sqlite4DebugPrintf("Skip   %s cost=%3d order=%c\n",
                  wherePathName(pFrom, iLoop, pWLoop), rCost,
                  isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
            }
#endif
            continue;
          }
          /* Add a new Path to the aTo[] set */
          if( nTo<mxChoice ){
            /* Increase the size of the aTo set by one */
            jj = nTo++;
          }else{
            /* New path replaces the prior worst to keep count below mxChoice */
            for(jj=nTo-1; aTo[jj].rCost<mxCost; jj--){ assert(jj>0); }
          }
          pTo = &aTo[jj];
#ifdef WHERETRACE_ENABLED
          if( sqlite4WhereTrace&0x4 ){
            sqlite4DebugPrintf("New    %s cost=%-3d order=%c\n",
                wherePathName(pFrom, iLoop, pWLoop), rCost,
                isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
          }
#endif
        }else{
          if( pTo->rCost<=rCost ){
#ifdef WHERETRACE_ENABLED
            if( sqlite4WhereTrace&0x4 ){
              sqlite4DebugPrintf(
                  "Skip   %s cost=%-3d order=%c",
                  wherePathName(pFrom, iLoop, pWLoop), rCost,
                  isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
              sqlite4DebugPrintf("   vs %s cost=%-3d order=%c\n",
                  wherePathName(pTo, iLoop+1, 0), pTo->rCost,
                  pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
            }
#endif
            testcase( pTo->rCost==rCost );
            continue;
          }
          testcase( pTo->rCost==rCost+1 );
          /* A new and better score for a previously created equivalent path */
#ifdef WHERETRACE_ENABLED
          if( sqlite4WhereTrace&0x4 ){
            sqlite4DebugPrintf(
                "Update %s cost=%-3d order=%c",
                wherePathName(pFrom, iLoop, pWLoop), rCost,
                isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
            sqlite4DebugPrintf("  was %s cost=%-3d order=%c\n",
                wherePathName(pTo, iLoop+1, 0), pTo->rCost,
                pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
          }
#endif
        }
        /* pWLoop is a winner.  Add it to the set of best so far */
        pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
        pTo->revLoop = revMask;
        pTo->nRow = pFrom->nRow + pWLoop->nOut;
        pTo->rCost = rCost;
        pTo->isOrderedValid = isOrderedValid;
        pTo->isOrdered = isOrdered;
        memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
        pTo->aLoop[iLoop] = pWLoop;
        if( nTo>=mxChoice ){
          mxCost = aTo[0].rCost;
          for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
            if( pTo->rCost>mxCost ) mxCost = pTo->rCost;
          }
        }
      }
    }

#ifdef WHERETRACE_ENABLED
    if( sqlite4WhereTrace>=2 ){
      sqlite4DebugPrintf("---- after round %d ----\n", iLoop);
      for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
        sqlite4DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
           wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
           pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
        if( pTo->isOrderedValid && pTo->isOrdered ){
          sqlite4DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
        }else{
          sqlite4DebugPrintf("\n");
        }
      }
    }
#endif

    /* Swap the roles of aFrom and aTo for the next generation */
    pFrom = aTo;
    aTo = aFrom;
    aFrom = pFrom;
    nFrom = nTo;
  }

  if( nFrom==0 ){
    sqlite4ErrorMsg(pParse, "no query solution");
    sqlite4DbFree(db, pSpace);
    return SQLITE4_ERROR;
  }
  
  /* Find the lowest cost path.  pFrom will be left pointing to that path */
  pFrom = aFrom;
  assert( nFrom==1 );
#if 0 /* The following is needed if nFrom is ever more than 1 */
  for(ii=1; ii<nFrom; ii++){
    if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
  }
#endif
  assert( pWInfo->nLevel==nLoop );
  /* Load the lowest cost path into pWInfo */
  for(iLoop=0; iLoop<nLoop; iLoop++){
    WhereLevel *pLevel = pWInfo->a + iLoop;
    pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
    pLevel->iFrom = pWLoop->iTab;
    pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
  }
  if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0
   && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0
   && pWInfo->eDistinct==WHERE_DISTINCT_NOOP
   && nRowEst
  ){
    Bitmask notUsed;
    int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
                 WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
    if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
  }
  if( pFrom->isOrdered ){
    if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
      pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
    }else{
      pWInfo->bOBSat = 1;
      pWInfo->revMask = pFrom->revLoop;
    }
  }
  pWInfo->nRowOut = pFrom->nRow;

  /* Free temporary memory and return success */
  sqlite4DbFree(db, pSpace);
  return SQLITE4_OK;
}

/*
** Most queries use only a single table (they are not joins) and have
** simple == constraints against indexed fields.  This routine attempts
** to plan those simple cases using much less ceremony than the
** general-purpose query planner, and thereby yield faster sqlite4_prepare()
** times for the common case.
**
** Return non-zero on success, if this query can be handled by this
** no-frills query planner.  Return zero if this query needs the 
** general-purpose query planner.
*/
static int whereShortCut(WhereLoopBuilder *pBuilder){
  WhereInfo *pWInfo;
  struct SrcListItem *pItem;
  WhereClause *pWC;
  WhereTerm *pTerm;
  WhereLoop *pLoop;
  int iCur;
  int j;
  Table *pTab;
  Index *pIdx;
  
  pWInfo = pBuilder->pWInfo;
  if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
  assert( pWInfo->pTabList->nSrc>=1 );
  pItem = pWInfo->pTabList->a;
  pTab = pItem->pTab;
  if( IsVirtual(pTab) ) return 0;
  if( pItem->zIndex ) return 0;
  iCur = pItem->iCursor;
  pWC = &pWInfo->sWC;
  pLoop = pBuilder->pNew;
  pLoop->wsFlags = 0;

  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    if( pIdx->onError==OE_None ) continue;
    for(j=0; j<pIdx->nColumn; j++){
      pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
      if( pTerm==0 ) break;
      whereLoopResize(pWInfo->pParse->db, pLoop, j);
      pLoop->aLTerm[j] = pTerm;
    }
    if( j!=pIdx->nColumn ) continue;
    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
    if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
      pLoop->wsFlags |= WHERE_IDX_ONLY;
    }
    pLoop->nLTerm = j;
    pLoop->u.btree.nEq = j;
    pLoop->u.btree.pIndex = pIdx;
    /* TUNING: Cost of a unique index lookup is 15 */
    pLoop->rRun = 39;  /* 39==whereCost(15) */
    break;
  }

  if( pLoop->wsFlags ){
    pLoop->nOut = (WhereCost)1;
    pWInfo->a[0].pWLoop = pLoop;
    pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur);
    pWInfo->a[0].iTabCur = iCur;
    pWInfo->nRowOut = 1;
    if( pWInfo->pOrderBy ) pWInfo->bOBSat =  1;
    if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
    }
#ifdef SQLITE4_DEBUG
    pLoop->cId = '0';
#endif
    return 1;
  }
  return 0;
}

/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop.  Later, the calling routine
** should invoke sqlite4WhereEnd() with the return value of this function
** in order to complete the WHERE clause processing.







<
<










|

|











|




|











|









|










<
<
<
<
<
<
<
<
<


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




|


|






|
<

<



|
|

>
|
|
>










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





<
<
<
<
<
<
<
|
<










|
|
<
<









|













|














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












|










|

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

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

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






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




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







4264
4265
4266
4267
4268
4269
4270


4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332









4333
4334








4335

4336


4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351

4352

4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372

























4373
4374
4375
4376
4377







4378

4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390


4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428






























4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453




































































4454


4455
4456







4457







4458







4459
4460

4461
4462
4463








4464
4465
4466








4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































4497
4498
4499
4500
4501
4502
4503
    **          Return     2                # Jump back to the Gosub
    **
    **       B: <after the loop>
    **
    */
    WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
    SrcList *pOrTab;       /* Shortened table list or OR-clause generation */



    int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
    int regKeyset = 0;                        /* Register for RowSet object */
    int regKey = 0;                           /* Register holding key */
    int iLoopBody = sqlite4VdbeMakeLabel(v);  /* Start of loop body */
    int iRetInit;                             /* Address of regReturn init */
    int untestedTerms = 0;             /* Some terms not completely tested */
    int ii;                            /* Loop counter */
    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
   
    pTerm = pLevel->plan.u.pTerm;
    assert( pTerm!=0 );
    assert( pTerm->eOperator==WO_OR );
    assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
    pOrWc = &pTerm->u.pOrInfo->wc;
    pLevel->op = OP_Return;
    pLevel->p1 = regReturn;

    /* Set up a new SrcList in pOrTab containing the table being scanned
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite4WhereBegin().
    */
    if( pWInfo->nLevel>1 ){
      int nNotReady;                 /* The number of notReady tables */
      SrcListItem *origSrc;     /* Original list of tables */
      nNotReady = pWInfo->nLevel - iLevel - 1;
      pOrTab = sqlite4StackAllocRaw(pParse->db,
                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
      if( pOrTab==0 ) return notReady;
      pOrTab->nAlloc = (i16)(nNotReady + 1);
      pOrTab->nSrc = pOrTab->nAlloc;
      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
      origSrc = pWInfo->pTabList->a;
      for(k=1; k<=nNotReady; k++){
        memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
      }
    }else{
      pOrTab = pWInfo->pTabList;
    }

    /* Initialize the keyset register to contain NULL. An SQL NULL is 
    ** equivalent to an empty rowset.
    **
    ** Also initialize regReturn to contain the address of the instruction 
    ** immediately following the OP_Return at the bottom of the loop. This
    ** is required in a few obscure LEFT JOIN cases where control jumps
    ** over the top of the loop into the body of it. In this case the 
    ** correct response for the end-of-loop code (the OP_Return) is to 
    ** fall through to the next instruction, just as an OP_Next does if
    ** called on an uninitialized cursor.
    */
    if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
      regKeyset = ++pParse->nMem;
      regKey = ++pParse->nMem;
      sqlite4VdbeAddOp2(v, OP_Null, 0, regKeyset);
    }
    iRetInit = sqlite4VdbeAddOp2(v, OP_Integer, 0, regReturn);

    /* If the original WHERE clause is z of the form:  (x1 OR x2 OR ...) AND y
    ** Then for every term xN, evaluate as the subexpression: xN AND z
    ** That way, terms in y that are factored into the disjunction will
    ** be picked up by the recursive calls to sqlite4WhereBegin() below.









    */
    if( pWC->nTerm>1 ){








      pAndExpr = sqlite4ExprAlloc(pParse->db, TK_AND, 0, 0);

      pAndExpr->pRight = pWhere;


    }

    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
        WhereInfo *pSubWInfo;          /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr;
        if( pAndExpr ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        pSubWInfo = sqlite4WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                        WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
                        WHERE_NO_AUTOINDEX | WHERE_ONETABLE_ONLY);

        if( pSubWInfo ){

          explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );
          if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
            int addrJump;
            sqlite4VdbeAddOp2(v, OP_RowKey, iCur, regKey);
            addrJump = sqlite4VdbeCurrentAddr(v) + 2;
            sqlite4VdbeAddOp4Int(v, OP_RowSetTest, 
                regKeyset, addrJump, regKey, ((ii==pOrWc->nTerm-1)?-1:ii)
            );
          }
          sqlite4VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);

          /* The pSubWInfo->untestedTerms flag means that this OR term
          ** contained one or more AND term from a notReady table.  The
          ** terms from the notReady table could not be tested and will
          ** need to be tested later.
          */
          if( pSubWInfo->untestedTerms ) untestedTerms = 1;


























          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite4WhereEnd(pSubWInfo);
        }
      }
    }







    sqlite4DbFree(pParse->db, pAndExpr);

    sqlite4VdbeChangeP1(v, iRetInit, sqlite4VdbeCurrentAddr(v));
    sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
    sqlite4VdbeResolveLabel(v, iLoopBody);

    if( pWInfo->nLevel>1 ) sqlite4StackFree(pParse->db, pOrTab);
    if( !untestedTerms ) disableTerm(pLevel, pTerm);
  }else
#endif /* SQLITE4_OMIT_OR_OPTIMIZATION */

  {
    /* 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 = SQLITE4_STMTSTATUS_FULLSCAN_STEP;
  }
  notReady &= ~getMask(pWC->pMaskSet, iCur);

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.
  **
  ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
  ** the use of indices become tests that are evaluated against each row of
  ** the relevant input tables.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
    testcase( pTerm->wtFlags & TERM_CODED );
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->prereqAll & notReady)!=0 ){
      testcase( pWInfo->untestedTerms==0
               && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
      pWInfo->untestedTerms = 1;
      continue;
    }
    pE = pTerm->pExpr;
    assert( pE!=0 );
    if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
      continue;
    }
    sqlite4ExprIfFalse(pParse, pE, addrCont, SQLITE4_JUMPIFNULL);
    pTerm->wtFlags |= TERM_CODED;
  }































  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.  
  */
  if( pLevel->iLeftJoin ){
    pLevel->addrFirst = sqlite4VdbeCurrentAddr(v);
    sqlite4VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
    VdbeComment((v, "record LEFT JOIN hit"));
    sqlite4ExprCacheClear(pParse);
    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
      testcase( pTerm->wtFlags & TERM_VIRTUAL );  /* IMP: R-30575-11662 */
      testcase( pTerm->wtFlags & TERM_CODED );
      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
      if( (pTerm->prereqAll & notReady)!=0 ){
        assert( pWInfo->untestedTerms );
        continue;
      }
      assert( pTerm->pExpr );
      sqlite4ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE4_JUMPIFNULL);
      pTerm->wtFlags |= TERM_CODED;
    }
  }
  sqlite4ReleaseTempReg(pParse, iReleaseReg);

  return notReady;
}







































































#if defined(SQLITE4_TEST)
/*







** The following variable holds a text description of query plan generated







** by the most recent call to sqlite4WhereBegin().  Each call to WhereBegin







** overwrites the previous.  This information is used for testing and
** analysis only.

*/
char sqlite4_query_plan[BMS*2*40];  /* Text of the join */
static int nQPlan = 0;              /* Next free slow in _query_plan[] */









#endif /* SQLITE4_TEST */










/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite4 *db, WhereInfo *pWInfo){
  if( ALWAYS(pWInfo) ){
    int i;
    for(i=0; i<pWInfo->nLevel; i++){
      sqlite4_index_info *pInfo = pWInfo->a[i].pIdxInfo;
      if( pInfo ){
        /* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */
        if( pInfo->needToFreeIdxStr ){
          sqlite4_free(db->pEnv, pInfo->idxStr);
        }
        sqlite4DbFree(db, pInfo);
      }
      if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
        Index *pIdx = pWInfo->a[i].plan.u.pIdx;
        if( pIdx ){
          assert( pIdx->eIndexType==SQLITE4_INDEX_TEMP );
          sqlite4DbFree(db, pIdx->zColAff);
          sqlite4DbFree(db, pIdx);
        }
      }
    }
    whereClauseClear(pWInfo->pWC);
    sqlite4DbFree(db, pWInfo);
  }
}








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop.  Later, the calling routine
** should invoke sqlite4WhereEnd() with the return value of this function
** in order to complete the WHERE clause processing.
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
**
** Note that the loops might not be nested in the order in which they
** appear in the FROM clause if a different order is better able to make
** use of indices.  Note also that when the IN operator appears in
** the WHERE clause, it might result in additional nested loops for
** scanning through all values on the right-hand side of the IN.
**
** There are Btree cursors associated with each table.  t1 uses cursor
** number pTabList->a[0].iCursor.  t2 uses the cursor pTabList->a[1].iCursor.
** And so forth.  This routine generates code to open those VDBE cursors
** and sqlite4WhereEnd() generates the code to close them.
**
** The code that sqlite4WhereBegin() generates leaves the cursors named
** in pTabList pointing at their appropriate entries.  The [...] code
** can use OP_Column and OP_Rowid opcodes on these cursors to extract







|







4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
**
** Note that the loops might not be nested in the order in which they
** appear in the FROM clause if a different order is better able to make
** use of indices.  Note also that when the IN operator appears in
** the WHERE clause, it might result in additional nested loops for
** scanning through all values on the right-hand side of the IN.
**
** There are cursors associated with each table.  t1 uses cursor
** number pTabList->a[0].iCursor.  t2 uses the cursor pTabList->a[1].iCursor.
** And so forth.  This routine generates code to open those VDBE cursors
** and sqlite4WhereEnd() generates the code to close them.
**
** The code that sqlite4WhereBegin() generates leaves the cursors named
** in pTabList pointing at their appropriate entries.  The [...] code
** can use OP_Column and OP_Rowid opcodes on these cursors to extract
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743









5744
5745
5746
5747
5748
5749
5750
5751
5752
5753

5754
5755
5756
5757
5758
5759
5760


5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
**        move the row2 cursor to a null row
**        goto start
**      fi
**    end
**
** ORDER BY CLAUSE PROCESSING
**
** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause
** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement
** if there is one.  If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.









*/
WhereInfo *sqlite4WhereBegin(
  Parse *pParse,        /* The parser context */
  SrcList *pTabList,    /* FROM clause: A list of all tables to be scanned */
  Expr *pWhere,         /* The WHERE clause */
  ExprList *pOrderBy,   /* An ORDER BY clause, or NULL */
  ExprList *pResultSet, /* Result set of the query */
  u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
  int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
){

  int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
  int nTabList;              /* Number of elements in pTabList */
  WhereInfo *pWInfo;         /* Will become the return value of this function */
  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
  Bitmask notReady;          /* Cursors that are not yet positioned */
  WhereLoopBuilder sWLB;     /* The WhereLoop builder */
  WhereMaskSet *pMaskSet;    /* The expression mask set */


  WhereLevel *pLevel;        /* A single level in pWInfo->a[] */
  WhereLoop *pLoop;          /* Pointer to a single WhereLoop object */
  int ii;                    /* Loop counter */
  sqlite4 *db;               /* Database connection */
  int rc;                    /* Return code */

  /* src4: In SQLite3, the caller would set this flag. */
  if( pResultSet ) wctrlFlags |= WHERE_WANT_DISTINCT;

  /* Variable initialization */
  db = pParse->db;
  memset(&sWLB, 0, sizeof(sWLB));
  sWLB.pOrderBy = pOrderBy;

  /* Disable the DISTINCT optimization if SQLITE4_DistinctOpt is set via
  ** sqlite4_test_ctrl(SQLITE4_TESTCTRL_OPTIMIZATIONS,...) */
  if( OptimizationDisabled(db, SQLITE4_DistinctOpt) ){
    wctrlFlags &= ~WHERE_WANT_DISTINCT;
  }

  /* The number of tables in the FROM clause is limited by the number of
  ** bits in a Bitmask 
  */
  testcase( pTabList->nSrc==BMS );
  if( pTabList->nSrc>BMS ){
    sqlite4ErrorMsg(pParse, "at most %d tables in a join", BMS);







|
<

|
>
>
>
>
>
>
>
>
>



|

|
|
|
<

>





<

>
>
|
|
|

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







4566
4567
4568
4569
4570
4571
4572
4573

4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592

4593
4594
4595
4596
4597
4598
4599

4600
4601
4602
4603
4604
4605
4606















4607
4608
4609
4610
4611
4612
4613
**        move the row2 cursor to a null row
**        goto start
**      fi
**    end
**
** ORDER BY CLAUSE PROCESSING
**
** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,

** if there is one.  If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
**
** If an index can be used so that the natural output order of the table
** scan is correct for the ORDER BY clause, then that index is used and
** *ppOrderBy is set to NULL.  This is an optimization that prevents an
** unnecessary sort of the result set if an index appropriate for the
** ORDER BY clause already exists.
**
** If the where clause loops cannot be arranged to provide the correct
** output order, then the *ppOrderBy is unchanged.
*/
WhereInfo *sqlite4WhereBegin(
  Parse *pParse,        /* The parser context */
  SrcList *pTabList,    /* A list of all tables to be scanned */
  Expr *pWhere,         /* The WHERE clause */
  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
  ExprList *pDistinct,  /* The select-list for DISTINCT queries - or NULL */
  u16 wctrlFlags        /* One of the WHERE_* flags defined in sqliteInt.h */

){
  int i;                     /* Loop counter */
  int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
  int nTabList;              /* Number of elements in pTabList */
  WhereInfo *pWInfo;         /* Will become the return value of this function */
  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
  Bitmask notReady;          /* Cursors that are not yet positioned */

  WhereMaskSet *pMaskSet;    /* The expression mask set */
  WhereClause *pWC;               /* Decomposition of the WHERE clause */
  SrcListItem *pTabItem;  /* A single entry from pTabList */
  WhereLevel *pLevel;             /* A single level in the pWInfo list */
  int iFrom;                      /* First unused FROM clause element */
  int andFlags;              /* AND-ed combination of all pWC->a[].wtFlags */
  sqlite4 *db;               /* Database connection */
















  /* The number of tables in the FROM clause is limited by the number of
  ** bits in a Bitmask 
  */
  testcase( pTabList->nSrc==BMS );
  if( pTabList->nSrc>BMS ){
    sqlite4ErrorMsg(pParse, "at most %d tables in a join", BMS);
5797
5798
5799
5800
5801
5802
5803

5804
5805




5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816

5817
5818
5819
5820

5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864





5865
5866
5867
5868
5869
5870

5871
5872





5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908



























5909
























































5910

5911
5912
5913
5914
5915
5916
5917




5918


5919



5920










5921
5922
5923

5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936

5937


5938


5939
5940



































5941
5942
5943









5944



















5945









5946





5947
5948
5949
5950
5951

5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993

5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030

6031

6032
6033
6034
6035
6036
6037
6038


6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073

6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099











































6100



6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200



6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219

6220


6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239

6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value. A single allocation is used to store the WhereInfo
  ** struct, the contents of WhereInfo.a[], the WhereClause structure
  ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
  ** field (type Bitmask) it must be aligned on an 8-byte boundary on
  ** some architectures. Hence the ROUND8() below.
  */

  nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
  pWInfo = sqlite4DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));




  if( db->mallocFailed ){
    sqlite4DbFree(db, pWInfo);
    pWInfo = 0;
    goto whereBeginError;
  }
  pWInfo->nLevel = nTabList;
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->pOrderBy = pOrderBy;
  pWInfo->pResultSet = pResultSet;
  pWInfo->iBreak = sqlite4VdbeMakeLabel(v);

  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  pMaskSet = &pWInfo->sMaskSet;
  sWLB.pWInfo = pWInfo;

  sWLB.pWC = &pWInfo->sWC;
  sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
  assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
  whereLoopInit(sWLB.pNew);
#ifdef SQLITE4_DEBUG
  sWLB.pNew->cId = '*';
#endif

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.
  */
  initMaskSet(pMaskSet);
  whereClauseInit(&pWInfo->sWC, pWInfo);
  sqlite4ExprCodeConstants(pParse, pWhere);
  whereSplit(&pWInfo->sWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
  sqlite4CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
    
  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (nTabList==0 || sqlite4ExprIsConstantNotJoin(pWhere)) ){
    sqlite4ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE4_JUMPIFNULL);
    pWhere = 0;
  }

  /* Special case: No FROM clause
  */
  if( nTabList==0 ){
    if( pOrderBy ) pWInfo->bOBSat = 1;
    if( wctrlFlags & WHERE_WANT_DISTINCT ){
      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
    }
  }

  /* Assign a bit from the bitmask to every term in the FROM clause.
  **
  ** When assigning bitmask values to FROM clause cursors, it must be
  ** the case that if X is the bitmask for the N-th FROM clause term then
  ** the bitmask for all FROM clause terms to the left of the N-th term
  ** is (X-1).   An expression from the ON clause of a LEFT JOIN can use
  ** its Expr.iRightJoinTable value to find the bitmask of the right table
  ** of the join.  Subtracting one from the right table bitmask gives a
  ** bitmask for all tables to the left of the join.  Knowing the bitmask
  ** for all tables to the left of a left join is important.  Ticket #3015.





  **
  ** Note that bitmasks are created for all pTabList->nSrc tables in
  ** pTabList, not just the first nTabList tables.  nTabList is normally
  ** equal to pTabList->nSrc but might be shortened to 1 if the
  ** WHERE_ONETABLE_ONLY flag is set.
  */

  for(ii=0; ii<pTabList->nSrc; ii++){
    createMask(pMaskSet, pTabList->a[ii].iCursor);





  }
#ifndef NDEBUG
  {
    Bitmask toTheLeft = 0;
    for(ii=0; ii<pTabList->nSrc; ii++){
      Bitmask m = getMask(pMaskSet, pTabList->a[ii].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, &pWInfo->sWC);
  if( db->mallocFailed ){
    goto whereBeginError;
  }

  /* If the ORDER BY (or GROUP BY) clause contains references to general
  ** expressions, then we won't be able to satisfy it using indices, so
  ** go ahead and disable it now.
  */
  if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
    for(ii=0; ii<pOrderBy->nExpr; ii++){
      Expr *pExpr = sqlite4ExprSkipCollate(pOrderBy->a[ii].pExpr);
      if( pExpr->op!=TK_COLUMN ){
        pWInfo->pOrderBy = pOrderBy = 0;
        break;
      }else if( pExpr->iColumn<0 ){
        break;
      }
    }



























  }


























































  if( wctrlFlags & WHERE_WANT_DISTINCT ){
    if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
      /* The DISTINCT marking is pointless.  Ignore it. */
      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
    }else if( pOrderBy==0 ){
      /* Try to ORDER BY the result set to make distinct processing easier */
      pWInfo->wctrlFlags |= WHERE_DISTINCTBY;




      pWInfo->pOrderBy = pResultSet;


    }



  }











  /* Construct the WhereLoop objects */
  WHERETRACE(0xffff,("*** Optimizer Start ***\n"));

  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
    rc = whereLoopAddAll(&sWLB);
    if( rc ) goto whereBeginError;
  
    /* Display all of the WhereLoop objects if wheretrace is enabled */
#ifdef WHERETRACE_ENABLED
    if( sqlite4WhereTrace ){
      WhereLoop *p;
      int i;
      static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
                                       "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
      for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
        p->cId = zLabel[i%sizeof(zLabel)];

        whereLoopPrint(p, pTabList);


      }


    }
#endif



































  
    wherePathSolver(pWInfo, 0);
    if( db->mallocFailed ) goto whereBeginError;









    if( pWInfo->pOrderBy ){



















       wherePathSolver(pWInfo, pWInfo->nRowOut+1);









       if( db->mallocFailed ) goto whereBeginError;





    }
  }
  if( pWInfo->pOrderBy==0 && (db->flags & SQLITE4_ReverseOrder)!=0 ){
     pWInfo->revMask = (Bitmask)(-1);
  }

  if( pParse->nErr || NEVER(db->mallocFailed) ){
    goto whereBeginError;
  }
#ifdef WHERETRACE_ENABLED
  if( sqlite4WhereTrace ){
    int ii;
    sqlite4DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
    if( pWInfo->bOBSat ){
      sqlite4DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask);
    }
    switch( pWInfo->eDistinct ){
      case WHERE_DISTINCT_UNIQUE: {
        sqlite4DebugPrintf("  DISTINCT=unique");
        break;
      }
      case WHERE_DISTINCT_ORDERED: {
        sqlite4DebugPrintf("  DISTINCT=ordered");
        break;
      }
      case WHERE_DISTINCT_UNORDERED: {
        sqlite4DebugPrintf("  DISTINCT=unordered");
        break;
      }
    }
    sqlite4DebugPrintf("\n");
    for(ii=0; ii<pWInfo->nLevel; ii++){
      whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList);
    }
  }
#endif
  /* Attempt to omit tables from the join that do not effect the result */
  if( pWInfo->nLevel>=2
   && pResultSet!=0
   && OptimizationEnabled(db, SQLITE4_OmitNoopJoin)
  ){
    Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
    if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy);
    while( pWInfo->nLevel>=2 ){
      WhereTerm *pTerm, *pEnd;
      pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
      if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
      if( (wctrlFlags & WHERE_WANT_DISTINCT)==0

       && (pLoop->wsFlags & WHERE_ONEROW)==0
      ){
        break;
      }
      if( (tabUsed & pLoop->maskSelf)!=0 ) break;
      pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
      for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
        if( (pTerm->prereqAll & pLoop->maskSelf)!=0
         && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
        ){
          break;
        }
      }
      if( pTerm<pEnd ) break;
      WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
      pWInfo->nLevel--;
      nTabList--;
    }
  }
  WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
  pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;

  /* If the caller is an UPDATE or DELETE statement that is requesting
  ** to use a one-pass algorithm, determine if this is appropriate.
  ** The one-pass algorithm only works if the WHERE clause constraints
  ** the statement to update a single row.
  */
  assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
   && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
    pWInfo->okOnePass = 1;
    pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
  }

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */

  notReady = ~(Bitmask)0;

  for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
    Table *pTab;     /* Table to open */
    int iDb;         /* Index of database containing table/index */
    struct SrcListItem *pTabItem;

    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;


    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);
    pLoop = pLevel->pWLoop;
    if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
      /* Do nothing */
    }else
#ifndef SQLITE4_OMIT_VIRTUALTABLE
    if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
      const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
      int iCur = pTabItem->iCursor;
      sqlite4VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
    }else if( IsVirtual(pTab) ){
      /* noop */
    }else
#endif
    if( (pLoop->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( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
      testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
    }
#ifndef SQLITE4_OMIT_AUTOMATIC_INDEX
    if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
      constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      if( pIx->eIndexType==SQLITE4_INDEX_PRIMARYKEY ){
        pLevel->iIdxCur = pTabItem->iCursor;
      }else{
        /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
        pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
        if( pIx->eIndexType!=SQLITE4_INDEX_FTS5 ){
          KeyInfo *pKey = sqlite4IndexKeyinfo(pParse, pIx);

          assert( pIx->pSchema==pTab->pSchema );
          assert( pLevel->iIdxCur>=0 );
          sqlite4VdbeAddOp4(v, OP_OpenRead, pLevel->iIdxCur, pIx->tnum, iDb,
              (char*)pKey, P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIx->zName));
        }
      }
    }
    sqlite4CodeVerifySchema(pParse, iDb);
    notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
  }
  pWInfo->iTop = sqlite4VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(ii=0; ii<nTabList; ii++){
    pLevel = &pWInfo->a[ii];
    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
    notReady = codeOneLoopStart(pWInfo, ii, notReady);
    pWInfo->iContinue = pLevel->addrCont;
  }












































  /* Done. */



  return pWInfo;

  /* Jump here if malloc fails */
whereBeginError:
  if( pWInfo ){
    pParse->nQueryLoop = pWInfo->savedNQueryLoop;
    whereInfoFree(db, pWInfo);
  }
  return 0;
}

/*
** Generate the end of the WHERE loop.  See comments on 
** sqlite4WhereBegin() for additional information.
*/
void sqlite4WhereEnd(WhereInfo *pWInfo){
  Parse *pParse = pWInfo->pParse;
  Vdbe *v = pParse->pVdbe;
  int i;
  WhereLevel *pLevel;
  WhereLoop *pLoop;
  SrcList *pTabList = pWInfo->pTabList;
  sqlite4 *db = pParse->db;

  /* Generate loop termination code.
  */
  sqlite4ExprCacheClear(pParse);
  for(i=pWInfo->nLevel-1; i>=0; i--){
    pLevel = &pWInfo->a[i];
    pLoop = pLevel->pWLoop;
    sqlite4VdbeResolveLabel(v, pLevel->addrCont);
    if( pLevel->op!=OP_Noop ){
      sqlite4VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
      sqlite4VdbeChangeP5(v, pLevel->p5);
    }
    if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
      struct InLoop *pIn;
      int j;
      sqlite4VdbeResolveLabel(v, pLevel->addrNxt);
      for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
        sqlite4VdbeJumpHere(v, pIn->addrInTop+1);
        sqlite4VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
        sqlite4VdbeJumpHere(v, pIn->addrInTop-1);
      }
      sqlite4DbFree(db, pLevel->u.in.aInLoop);
    }
    sqlite4VdbeResolveLabel(v, pLevel->addrBrk);
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite4VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
      assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
           || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
      if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
        sqlite4VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
      }
      if( pLoop->wsFlags & WHERE_INDEXED ){
        sqlite4VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
      }
      if( pLevel->op==OP_Return ){
        sqlite4VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
      }else{
        sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
      }
      sqlite4VdbeJumpHere(v, addr);
    }
  }

  /* The "break" point is here, just past the end of the outer loop.
  ** Set it.
  */
  sqlite4VdbeResolveLabel(v, pWInfo->iBreak);

  /* Close all of the cursors that were opened by sqlite4WhereBegin.
  */
  assert( pWInfo->nLevel<=pTabList->nSrc );
  for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
    Index *pIdx = 0;
    struct SrcListItem *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    pLoop = pLevel->pWLoop;
    if( (pTab->tabFlags & TF_Ephemeral)==0
     && pTab->pSelect==0
     && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
    ){
      int ws = pLoop->wsFlags;
      if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
        sqlite4VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
      }
      if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_AUTO_INDEX)==0 ){
        if( pLevel->iIdxCur!=pTabItem->iCursor ){
          sqlite4VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
        }
      }
    }

    /* If this scan uses an index, make VDBE code substitutions to read data
    ** from the index instead of from the table where possible.  In some cases
    ** this optimization prevents the table from ever being read, which can
    ** yield a significant performance boost.



    ** 
    ** 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( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
      pIdx = pLoop->u.btree.pIndex;
    }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
      pIdx = pLevel->u.pCovidx;
    }
    if( pIdx && pIdx->eIndexType!=SQLITE4_INDEX_PRIMARYKEY 
     && !db->mallocFailed 
    ){
      int *aiCover = pIdx->aiCover;
      int nCover = pIdx->nCover;
      int k, j, last;
      VdbeOp *pOp;




      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
      last = sqlite4VdbeCurrentAddr(v);
      for(k=pWInfo->iTop; k<last; k++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          for(j=0; j<nCover; j++){
            if( pOp->p2==aiCover[j] ){
              pOp->p2 = j;
              pOp->p1 = pLevel->iIdxCur;
              break;
            }
          }
          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || j<nCover );
        }else if( pOp->opcode==OP_RowKey ){
          Index *pPk = sqlite4FindPrimaryKey(pTab, 0);
          pOp->p3 = pPk->tnum;
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowkey;
        }

      }
    }

    if( (pLoop->wsFlags & WHERE_INDEXED)
     && (pLoop->u.btree.pIndex->eIndexType==SQLITE4_INDEX_FTS5)
    ){
      VdbeOp *pOp;
      VdbeOp *pEnd;

      assert( pLevel->iTabCur!=pLevel->iIdxCur );
      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
      pEnd = &pOp[sqlite4VdbeCurrentAddr(v) - pWInfo->iTop];







>

|
>
>
>
>








<
<

>


|
|
>
|
<
<
<
|
<
<





|

|
<









<
<
<
<
<
<
<
<
<










>
>
>
>
>






>
|
|
>
>
>
>
>




|
|






|
<
<
<
<
|




|
|
|

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

>
|


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






|
<

|





>

>
|


<



>
>

<




|



<
<


|



|
|


|
|


|
|


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



|









|
|
|
|



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




















<








<





|





|








|
|
|


|


















|

<
|


<




|



|






|
|
<
|
>
>
>







<
<
<
<
<
<
|
<
<
<
<

>

>
>

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

<

>



|
|







4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645


4646
4647
4648
4649
4650
4651
4652
4653



4654


4655
4656
4657
4658
4659
4660
4661
4662

4663
4664
4665
4666
4667
4668
4669
4670
4671









4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713




4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724


4725



4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815


4816


4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839


4840
4841


4842
4843





4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891

4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
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
4981
4982
4983
4984
4985
4986


4987
4988
4989
4990
4991
4992
4993
4994
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
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099

5100
5101
5102
5103
5104
5105
5106
5107

5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153

5154
5155
5156

5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173

5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184






5185




5186
5187
5188
5189
5190
5191
5192








5193


5194

5195
5196

5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value. A single allocation is used to store the WhereInfo
  ** struct, the contents of WhereInfo.a[], the WhereClause structure
  ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
  ** field (type Bitmask) it must be aligned on an 8-byte boundary on
  ** some architectures. Hence the ROUND8() below.
  */
  db = pParse->db;
  nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
  pWInfo = sqlite4DbMallocZero(db, 
      nByteWInfo + 
      sizeof(WhereClause) +
      sizeof(WhereMaskSet)
  );
  if( db->mallocFailed ){
    sqlite4DbFree(db, pWInfo);
    pWInfo = 0;
    goto whereBeginError;
  }
  pWInfo->nLevel = nTabList;
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;


  pWInfo->iBreak = sqlite4VdbeMakeLabel(v);
  pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  pMaskSet = (WhereMaskSet*)&pWC[1];

  /* Disable the DISTINCT optimization if SQLITE4_DistinctOpt is set via
  ** sqlite4_test_ctrl(SQLITE4_TESTCTRL_OPTIMIZATIONS,...) */



  if( db->flags & SQLITE4_DistinctOpt ) pDistinct = 0;



  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.
  */
  initMaskSet(pMaskSet);
  whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags);
  sqlite4ExprCodeConstants(pParse, pWhere);
  whereSplit(pWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */

    
  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (nTabList==0 || sqlite4ExprIsConstantNotJoin(pWhere)) ){
    sqlite4ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE4_JUMPIFNULL);
    pWhere = 0;
  }










  /* Assign a bit from the bitmask to every term in the FROM clause.
  **
  ** When assigning bitmask values to FROM clause cursors, it must be
  ** the case that if X is the bitmask for the N-th FROM clause term then
  ** the bitmask for all FROM clause terms to the left of the N-th term
  ** is (X-1).   An expression from the ON clause of a LEFT JOIN can use
  ** its Expr.iRightJoinTable value to find the bitmask of the right table
  ** of the join.  Subtracting one from the right table bitmask gives a
  ** bitmask for all tables to the left of the join.  Knowing the bitmask
  ** for all tables to the left of a left join is important.  Ticket #3015.
  **
  ** Configure the WhereClause.vmask variable so that bits that correspond
  ** to virtual table cursors are set. This is used to selectively disable 
  ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful 
  ** with virtual tables.
  **
  ** Note that bitmasks are created for all pTabList->nSrc tables in
  ** pTabList, not just the first nTabList tables.  nTabList is normally
  ** equal to pTabList->nSrc but might be shortened to 1 if the
  ** WHERE_ONETABLE_ONLY flag is set.
  */
  assert( pWC->vmask==0 && pMaskSet->n==0 );
  for(i=0; i<pTabList->nSrc; i++){
    createMask(pMaskSet, pTabList->a[i].iCursor);
#ifndef SQLITE4_OMIT_VIRTUALTABLE
    if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){
      pWC->vmask |= ((Bitmask)1 << i);
    }
#endif
  }
#ifndef NDEBUG
  {
    Bitmask toTheLeft = 0;
    for(i=0; i<pTabList->nSrc; i++){
      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
  ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
  */
  if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){
    pDistinct = 0;


    pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;



  }

  /* Chose the best index to use for each table in the FROM clause.
  **
  ** This loop fills in the following fields:
  **
  **   pWInfo->a[].pIdx      The index to use for this level of the loop.
  **   pWInfo->a[].wsFlags   WHERE_xxx flags associated with pIdx
  **   pWInfo->a[].nEq       The number of == and IN constraints
  **   pWInfo->a[].iFrom     Which term of the FROM clause is being coded
  **   pWInfo->a[].iTabCur   The VDBE cursor for the database table
  **   pWInfo->a[].iIdxCur   The VDBE cursor for the index
  **   pWInfo->a[].pTerm     When wsFlags==WO_OR, the OR-clause term
  **
  ** This loop also figures out the nesting order of tables in the FROM
  ** clause.
  */
  notReady = ~(Bitmask)0;
  andFlags = ~0;
  WHERETRACE(("*** Optimizer Start ***\n"));
  for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
    WhereCost bestPlan;         /* Most efficient plan seen so far */
    Index *pIdx;                /* Index for FROM table at pTabItem */
    int j;                      /* For looping over FROM tables */
    int bestJ = -1;             /* The value of j */
    Bitmask m;                  /* Bitmask value for j or bestJ */
    int isOptimal;              /* Iterator for optimal/non-optimal search */
    int nUnconstrained;         /* Number tables without INDEXED BY */
    Bitmask notIndexed;         /* Mask of tables that cannot use an index */

    memset(&bestPlan, 0, sizeof(bestPlan));
    bestPlan.rCost = SQLITE4_BIG_DBL;
    WHERETRACE(("*** Begin search for loop %d ***\n", i));

    /* Loop through the remaining entries in the FROM clause to find the
    ** next nested loop. The loop tests all FROM clause entries
    ** either once or twice. 
    **
    ** The first test is always performed if there are two or more entries
    ** remaining and never performed if there is only one FROM clause entry
    ** to choose from.  The first test looks for an "optimal" scan.  In
    ** this context an optimal scan is one that uses the same strategy
    ** for the given FROM clause entry as would be selected if the entry
    ** were used as the innermost nested loop.  In other words, a table
    ** is chosen such that the cost of running that table cannot be reduced
    ** by waiting for other tables to run first.  This "optimal" test works
    ** by first assuming that the FROM clause is on the inner loop and finding
    ** its query plan, then checking to see if that query plan uses any
    ** other FROM clause terms that are notReady.  If no notReady terms are
    ** used then the "optimal" query plan works.
    **
    ** Note that the WhereCost.nRow parameter for an optimal scan might
    ** not be as small as it would be if the table really were the innermost
    ** join.  The nRow value can be reduced by WHERE clause constraints
    ** that do not use indices.  But this nRow reduction only happens if the
    ** table really is the innermost join.  
    **
    ** The second loop iteration is only performed if no optimal scan
    ** strategies were found by the first iteration. This second iteration
    ** is used to search for the lowest cost scan overall.
    **
    ** Previous versions of SQLite performed only the second iteration -
    ** the next outermost loop was always that with the lowest overall
    ** cost. However, this meant that SQLite could select the wrong plan
    ** for scripts such as the following:
    **   
    **   CREATE TABLE t1(a, b); 
    **   CREATE TABLE t2(c, d);
    **   SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
    **
    ** The best strategy is to iterate through table t1 first. However it
    ** is not possible to determine this with a simple greedy algorithm.
    ** Since the cost of a linear scan through table t2 is the same 
    ** as the cost of a linear scan through table t1, a simple greedy 
    ** algorithm may choose to use t2 for the outer loop, which is a much
    ** costlier approach.
    */
    nUnconstrained = 0;
    notIndexed = 0;
    for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){
      Bitmask mask;             /* Mask of tables not yet ready */
      for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
        int doNotReorder;    /* True if this table should not be reordered */
        WhereCost sCost;     /* Cost information from best[Virtual]Index() */
        ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */
        ExprList *pDist;     /* DISTINCT clause for index to optimize */
  
        doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
        if( j!=iFrom && doNotReorder ) break;
        m = getMask(pMaskSet, pTabItem->iCursor);


        if( (m & notReady)==0 ){


          if( j==iFrom ) iFrom++;
          continue;
        }
        mask = (isOptimal ? m : notReady);
        pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
        pDist = (i==0 ? pDistinct : 0);
        if( pTabItem->pIndex==0 ) nUnconstrained++;
  
        WHERETRACE(("=== trying table %d with isOptimal=%d ===\n",
                    j, isOptimal));
        assert( pTabItem->pTab );

        if( bestMatchIdx(pParse, pWC, pTabItem, notReady, &sCost) ){
          /* no-op */
        }else
#ifndef SQLITE4_OMIT_VIRTUALTABLE
        if( IsVirtual(pTabItem->pTab) ){
          sqlite4_index_info **pp = &pWInfo->a[j].pIdxInfo;
          bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
                           &sCost, pp);
        }else 
#endif
        {


          bestKVIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
              pDist, &sCost);


        }






        assert( isOptimal || (sCost.used&notReady)==0 );

        /* If an INDEXED BY clause is present, then the plan must use that
        ** index if it uses any index at all */
        assert( pTabItem->pIndex==0 
                  || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                  || sCost.plan.u.pIdx==pTabItem->pIndex );

        if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
          notIndexed |= m;
        }

        /* Conditions under which this table becomes the best so far:
        **
        **   (1) The table must not depend on other tables that have not
        **       yet run.
        **
        **   (2) A full-table-scan plan cannot supercede indexed plan unless
        **       the full-table-scan is an "optimal" plan as defined above.
        **
        **   (3) All tables have an INDEXED BY clause or this table lacks an
        **       INDEXED BY clause or this table uses the specific
        **       index specified by its INDEXED BY clause.  This rule ensures
        **       that a best-so-far is always selected even if an impossible
        **       combination of INDEXED BY clauses are given.  The error
        **       will be detected and relayed back to the application later.
        **       The NEVER() comes about because rule (2) above prevents
        **       An indexable full-table-scan from reaching rule (3).
        **
        **   (4) The plan cost must be lower than prior plans or else the
        **       cost must be the same and the number of rows must be lower.
        */
        if( (sCost.used&notReady)==0                       /* (1) */
            && (bestJ<0 || (notIndexed&m)!=0               /* (2) */
                || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
            && (nUnconstrained==0 || pTabItem->pIndex==0   /* (3) */
                || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
            && (bestJ<0 || sCost.rCost<bestPlan.rCost      /* (4) */
                || (sCost.rCost<=bestPlan.rCost 
                 && sCost.plan.nRow<bestPlan.plan.nRow))
        ){
          WHERETRACE(("=== table %d is best so far"
                      " with cost=%g and nRow=%g\n",
                      j, sCost.rCost, sCost.plan.nRow));
          bestPlan = sCost;
          bestJ = j;
        }

        if( doNotReorder ) break;
      }
    }
    assert( bestJ>=0 );
    assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
    WHERETRACE(("*** Optimizer selects table %d for loop %d"
                " with cost=%g and nRow=%g\n",
                bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
    /* The ALWAYS() that follows was added to hush up clang scan-build */
    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
      *ppOrderBy = 0;
    }
    if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
      assert( pWInfo->eDistinct==0 );
      pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
    }
    andFlags &= bestPlan.plan.wsFlags;
    pLevel->plan = bestPlan.plan;
    testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
    testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
    if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
      pLevel->iIdxCur = pParse->nTab++;
    }else{
      pLevel->iIdxCur = -1;
    }
    notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
    pLevel->iFrom = (u8)bestJ;
    if( bestPlan.plan.nRow>=(double)1 ){
      pParse->nQueryLoop *= bestPlan.plan.nRow;
    }

    /* Check that if the table scanned by this loop iteration had an
    ** INDEXED BY clause attached to it, that the named index is being
    ** used for the scan. If not, then query compilation has failed.
    ** Return an error.
    */
    pIdx = pTabList->a[bestJ].pIndex;
    if( pIdx ){
      if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){
        sqlite4ErrorMsg(pParse, "cannot use index: %s", pIdx->zName);
        goto whereBeginError;
      }else{
        /* If an INDEXED BY clause is used, the bestIndex() function is
        ** guaranteed to find the index specified in the INDEXED BY clause
        ** if it find an index at all. */
        assert( bestPlan.plan.u.pIdx==pIdx );
      }
    }


  }
  WHERETRACE(("*** Optimizer Finished ***\n"));
  if( pParse->nErr || db->mallocFailed ){
    goto whereBeginError;
  }












  /* If the total query only selects a single row, then the ORDER BY

  ** clause is irrelevant.
























  */
  if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){




    *ppOrderBy = 0;





  }










  /* If the caller is an UPDATE or DELETE statement that is requesting
  ** to use a one-pass algorithm, determine if this is appropriate.
  ** The one-pass algorithm only works if the WHERE clause constraints
  ** the statement to update a single row.
  */
  assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){

    pWInfo->okOnePass = 1;
    pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
  }

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  sqlite4CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  notReady = ~(Bitmask)0;
  pWInfo->nRowOut = (double)1;
  for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
    Table *pTab;     /* Table to open */
    int iDb;         /* Index of database containing table/index */


    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;
    pLevel->iTabCur = pTabItem->iCursor;
    pWInfo->nRowOut *= pLevel->plan.nRow;
    iDb = sqlite4SchemaToIndex(db, pTab->pSchema);

    if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
      /* Do nothing */
    }else
#ifndef SQLITE4_OMIT_VIRTUALTABLE
    if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
      const char *pVTab = (const char *)sqlite4GetVTable(db, pTab);
      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 );
    }
#ifndef SQLITE4_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==SQLITE4_INDEX_PRIMARYKEY ){
        pLevel->iIdxCur = pTabItem->iCursor;



      }else if( pIx->eIndexType!=SQLITE4_INDEX_FTS5 ){
        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;

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(i=0; i<nTabList; i++){
    pLevel = &pWInfo->a[i];
    explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere);
    pWInfo->iContinue = pLevel->addrCont;
  }

#ifdef SQLITE4_TEST  /* For testing and debugging use only */
  /* Record in the query plan information about the current table
  ** and the index used to access it (if any).  If the table itself
  ** is not used, its name is just '{}'.  If no index is used
  ** the index is listed as "{}".  If the primary key is used the
  ** index name is '*'.
  */
  for(i=0; i<nTabList; i++){
    char *z;
    int n;
    pLevel = &pWInfo->a[i];
    pTabItem = &pTabList->a[pLevel->iFrom];
    z = pTabItem->zAlias;
    if( z==0 ) z = pTabItem->pTab->zName;
    n = sqlite4Strlen30(z);
    if( n+nQPlan < sizeof(sqlite4_query_plan)-10 ){
      if( pLevel->plan.wsFlags & WHERE_IDX_ONLY ){
        memcpy(&sqlite4_query_plan[nQPlan], "{}", 2);
        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{
      memcpy(&sqlite4_query_plan[nQPlan], "{} ", 3);
      nQPlan += 3;
    }
  }
  while( nQPlan>0 && sqlite4_query_plan[nQPlan-1]==' ' ){
    sqlite4_query_plan[--nQPlan] = 0;
  }
  sqlite4_query_plan[nQPlan] = 0;
  nQPlan = 0;
#endif /* SQLITE4_TEST // Testing and debugging use only */

  /* Record the continuation address in the WhereInfo structure. Then
  ** clean up and return.
  */
  return pWInfo;

  /* Jump here if malloc fails */
whereBeginError:
  if( pWInfo ){
    pParse->nQueryLoop = pWInfo->savedNQueryLoop;
    whereInfoFree(db, pWInfo);
  }
  return 0;
}

/*
** Generate the end of the WHERE loop.  See comments on 
** sqlite4WhereBegin() for additional information.
*/
void sqlite4WhereEnd(WhereInfo *pWInfo){
  Parse *pParse = pWInfo->pParse;
  Vdbe *v = pParse->pVdbe;
  int i;
  WhereLevel *pLevel;

  SrcList *pTabList = pWInfo->pTabList;
  sqlite4 *db = pParse->db;

  /* Generate loop termination code.
  */
  sqlite4ExprCacheClear(pParse);
  for(i=pWInfo->nLevel-1; i>=0; i--){
    pLevel = &pWInfo->a[i];

    sqlite4VdbeResolveLabel(v, pLevel->addrCont);
    if( pLevel->op!=OP_Noop ){
      sqlite4VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
      sqlite4VdbeChangeP5(v, pLevel->p5);
    }
    if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
      struct InLoop *pIn;
      int j;
      sqlite4VdbeResolveLabel(v, pLevel->addrNxt);
      for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
        sqlite4VdbeJumpHere(v, pIn->addrInTop+1);
        sqlite4VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
        sqlite4VdbeJumpHere(v, pIn->addrInTop-1);
      }
      sqlite4DbFree(db, pLevel->u.in.aInLoop);
    }
    sqlite4VdbeResolveLabel(v, pLevel->addrBrk);
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite4VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
      assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
           || (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 );
      if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){
        sqlite4VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
      }
      if( pLevel->iIdxCur>=0 ){
        sqlite4VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
      }
      if( pLevel->op==OP_Return ){
        sqlite4VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
      }else{
        sqlite4VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
      }
      sqlite4VdbeJumpHere(v, addr);
    }
  }

  /* The "break" point is here, just past the end of the outer loop.
  ** Set it.
  */
  sqlite4VdbeResolveLabel(v, pWInfo->iBreak);

  /* Close all of the cursors that were opened by sqlite4WhereBegin.
  */
  assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
  for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){

    SrcListItem *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );

    if( (pTab->tabFlags & TF_Ephemeral)==0
     && pTab->pSelect==0
     && (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
    ** seeking the table cursor to the record corresponding to the current
    ** position in the index.
    ** 
    ** 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_TEMP_INDEX) && !db->mallocFailed ){




      VdbeOp *pOp;
      VdbeOp *pEnd;

      assert( pLevel->plan.u.pIdx );
      assert( pLevel->iTabCur!=pLevel->iIdxCur );
      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
      pEnd = &pOp[sqlite4VdbeCurrentAddr(v) - pWInfo->iTop];











      while( pOp<pEnd ){

        if( pOp->p1==pLevel->iTabCur && pOp->opcode==OP_Column ){
          pOp->p1 = pLevel->iIdxCur;

        }
        pOp++;
      }
    }

    if( (pLevel->plan.wsFlags & WHERE_INDEXED)
     && (pLevel->plan.u.pIdx->eIndexType==SQLITE4_INDEX_FTS5)
    ){
      VdbeOp *pOp;
      VdbeOp *pEnd;

      assert( pLevel->iTabCur!=pLevel->iIdxCur );
      pOp = sqlite4VdbeGetOp(v, pWInfo->iTop);
      pEnd = &pOp[sqlite4VdbeCurrentAddr(v) - pWInfo->iTop];
Changes to test/alter.test.
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
  }
} [list \
     table t1                              t1             \
     index t1i1                            t1             \
     index t1i2                            t1             \
     table t1'x1                           t1'x1          \
     index i3                              t1'x1          \
     index {sqlite_t1'x1_unique1}      t1'x1          \

     table {temp table}                    {temp table}   \
     index i2                              {temp table}   \
     index {sqlite_temp table_unique1}     {temp table}   \
  ]

# Make some changes
#
integrity_check alter-1.3.0
do_test alter-1.3 {
  execsql {







|
>


|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  }
} [list \
     table t1                              t1             \
     index t1i1                            t1             \
     index t1i2                            t1             \
     table t1'x1                           t1'x1          \
     index i3                              t1'x1          \
     index {sqlite_autoindex_t1'x1_1}      t1'x1          \
     index {sqlite_autoindex_t1'x1_2}      t1'x1          \
     table {temp table}                    {temp table}   \
     index i2                              {temp table}   \
     index {sqlite_autoindex_temp table_1} {temp table}   \
  ]

# Make some changes
#
integrity_check alter-1.3.0
do_test alter-1.3 {
  execsql {
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
  }
} [list \
     table -t1-                         -t1-        \
     index t1i1                         -t1-        \
     index t1i2                         -t1-        \
     table T2                           T2          \
     index i3                           T2          \
     index {sqlite_T2_unique1}          T2          \

     table {TempTab}                    {TempTab}   \
     index i2                           {TempTab}   \
     index {sqlite_TempTab_unique1}     {TempTab}   \
  ]

# Make sure the changes persist after restarting the database.
# (The TEMP table will not persist, of course.)
#
ifcapable tempdb {
  do_test alter-1.6 {







|
>


|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  }
} [list \
     table -t1-                         -t1-        \
     index t1i1                         -t1-        \
     index t1i2                         -t1-        \
     table T2                           T2          \
     index i3                           T2          \
     index {sqlite_autoindex_T2_1}      T2          \
     index {sqlite_autoindex_T2_2}      T2          \
     table {TempTab}                    {TempTab}   \
     index i2                           {TempTab}   \
     index {sqlite_autoindex_TempTab_1} {TempTab}   \
  ]

# Make sure the changes persist after restarting the database.
# (The TEMP table will not persist, of course.)
#
ifcapable tempdb {
  do_test alter-1.6 {
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
    }
  } [list \
       table -t1-                         -t1-           \
       index t1i1                         -t1-           \
       index t1i2                         -t1-           \
       table T2                           T2          \
       index i3                           T2          \
       index {sqlite_T2_unique1}          T2          \

    ]
} else {
  execsql {
    DROP TABLE TempTab;
  }
}








|
>







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    }
  } [list \
       table -t1-                         -t1-           \
       index t1i1                         -t1-           \
       index t1i2                         -t1-           \
       table T2                           T2          \
       index i3                           T2          \
       index {sqlite_autoindex_T2_1}      T2          \
       index {sqlite_autoindex_T2_2}      T2          \
    ]
} else {
  execsql {
    DROP TABLE TempTab;
  }
}

206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
  }
} [list \
     table *t1*                         *t1*           \
     index t1i1                         *t1*           \
     index t1i2                         *t1*           \
     table <t2>                         <t2>          \
     index i3                           <t2>          \
     index {sqlite_<t2>_unique1}    <t2>          \

  ]

# Check that ALTER TABLE works on attached databases.
#
ifcapable attach {
  do_test alter-1.8.1 {
    forcedelete test2.db







|
>







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
  }
} [list \
     table *t1*                         *t1*           \
     index t1i1                         *t1*           \
     index t1i2                         *t1*           \
     table <t2>                         <t2>          \
     index i3                           <t2>          \
     index {sqlite_autoindex_<t2>_1}    <t2>          \
     index {sqlite_autoindex_<t2>_2}    <t2>          \
  ]

# Check that ALTER TABLE works on attached databases.
#
ifcapable attach {
  do_test alter-1.8.1 {
    forcedelete test2.db
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
do_test alter-6.1 {
  string length $::tbl_name
} {7}
do_test alter-6.2 {
  execsql "
    CREATE TABLE ${tbl_name}(a, b, c);
  "
  set ::oid [execsql {SELECT max(rowid) FROM sqlite_master}]
  execsql "
    SELECT sql FROM sqlite_master WHERE rowid = $::oid;
  "
} "{CREATE TABLE ${::tbl_name}(a, b, c)}"
execsql "
  SELECT * FROM ${::tbl_name}
"
set ::tbl_name2 "abcXdef"
do_test alter-6.3 {
  execsql "
    ALTER TABLE $::tbl_name RENAME TO $::tbl_name2 
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE rowid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}"
do_test alter-6.4 {
  execsql "
    ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE rowid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}"
set ::col_name ghi\1234\jkl
do_test alter-6.5 {
  execsql "
    ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE rowid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}"
set ::col_name2 B\3421\A
do_test alter-6.6 {
  db close
  sqlite4 db test.db
  execsql "
    ALTER TABLE $::tbl_name ADD COLUMN $::col_name2
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE rowid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}"
do_test alter-6.7 {
  execsql "
    INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5);
    SELECT $::col_name, $::col_name2 FROM $::tbl_name;
  "







|

|











|







|








|










|







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
do_test alter-6.1 {
  string length $::tbl_name
} {7}
do_test alter-6.2 {
  execsql "
    CREATE TABLE ${tbl_name}(a, b, c);
  "
  set ::oid [execsql {SELECT max(oid) FROM sqlite_master}]
  execsql "
    SELECT sql FROM sqlite_master WHERE oid = $::oid;
  "
} "{CREATE TABLE ${::tbl_name}(a, b, c)}"
execsql "
  SELECT * FROM ${::tbl_name}
"
set ::tbl_name2 "abcXdef"
do_test alter-6.3 {
  execsql "
    ALTER TABLE $::tbl_name RENAME TO $::tbl_name2 
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE oid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}"
do_test alter-6.4 {
  execsql "
    ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE oid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}"
set ::col_name ghi\1234\jkl
do_test alter-6.5 {
  execsql "
    ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE oid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}"
set ::col_name2 B\3421\A
do_test alter-6.6 {
  db close
  sqlite4 db test.db
  execsql "
    ALTER TABLE $::tbl_name ADD COLUMN $::col_name2
  "
  execsql "
    SELECT sql FROM sqlite_master WHERE oid = $::oid
  "
} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}"
do_test alter-6.7 {
  execsql "
    INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5);
    SELECT $::col_name, $::col_name2 FROM $::tbl_name;
  "
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

#--------------------------------------------------------------------------
# alter-9.X - Special test: Make sure the sqlite_rename_trigger() and
# rename_table() functions do not crash when handed bad input.
#
ifcapable trigger {
  do_test alter-9.1 {
    execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)}
  } {{}}
}
do_test alter-9.2 {
  execsql {
    SELECT SQLITE_RENAME_TABLE(0,0);
    SELECT SQLITE_RENAME_TABLE(10,20);
    SELECT SQLITE_RENAME_TABLE('foo', 'foo');
  }
} {{} {} {}}

#------------------------------------------------------------------------
# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters 
# in the names.
#
do_test alter-10.1 {
  execsql "CREATE TABLE xyz(x UNIQUE)"
  execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
} [list xyz\u1234abc]
do_test alter-10.2 {
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_*unique*'}
} [list sqlite_xyz\u1234abc_unique1]
do_test alter-10.3 {
  execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
} [list xyzabc]
do_test alter-10.4 {
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_*unique*'}
} [list sqlite_xyzabc_unique1]

do_test alter-11.1 {
  sqlite4_exec db {CREATE TABLE t11(%c6%c6)}
  execsql {
    ALTER TABLE t11 ADD COLUMN abc;
  }
  catchsql {







|




|
|
|













|
|





|
|







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

#--------------------------------------------------------------------------
# alter-9.X - Special test: Make sure the sqlite_rename_trigger() and
# rename_table() functions do not crash when handed bad input.
#
ifcapable trigger {
  do_test alter-9.1 {
    execsql {SELECT SQLITE4_RENAME_TRIGGER(0,0)}
  } {{}}
}
do_test alter-9.2 {
  execsql {
    SELECT SQLITE4_RENAME_TABLE(0,0);
    SELECT SQLITE4_RENAME_TABLE(10,20);
    SELECT SQLITE4_RENAME_TABLE('foo', 'foo');
  }
} {{} {} {}}

#------------------------------------------------------------------------
# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters 
# in the names.
#
do_test alter-10.1 {
  execsql "CREATE TABLE xyz(x UNIQUE)"
  execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
} [list xyz\u1234abc]
do_test alter-10.2 {
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
} [list sqlite_autoindex_xyz\u1234abc_1]
do_test alter-10.3 {
  execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
} [list xyzabc]
do_test alter-10.4 {
  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
} [list sqlite_autoindex_xyzabc_1]

do_test alter-11.1 {
  sqlite4_exec db {CREATE TABLE t11(%c6%c6)}
  execsql {
    ALTER TABLE t11 ADD COLUMN abc;
  }
  catchsql {
Changes to test/alter3.test.
177
178
179
180
181
182
183





184
185
186
187
188
189
190
} {}
do_test alter3-3.2 {
  execsql {
    ALTER TABLE t1 ADD c;
    SELECT * FROM t1;
  }
} {1 100 {} 2 300 {}}





ifcapable schema_version {
  do_test alter3-3.4 {
    execsql {
      PRAGMA schema_version;
    }
  } {11}
}







>
>
>
>
>







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
} {}
do_test alter3-3.2 {
  execsql {
    ALTER TABLE t1 ADD c;
    SELECT * FROM t1;
  }
} {1 100 {} 2 300 {}}
if {!$has_codec} {
  do_test alter3-3.3 {
    get_file_format
  } {3}
}
ifcapable schema_version {
  do_test alter3-3.4 {
    execsql {
      PRAGMA schema_version;
    }
  } {11}
}
208
209
210
211
212
213
214





215
216
217
218
219
220
221
} {}
do_test alter3-4.2 {
  execsql {
    ALTER TABLE t1 ADD c DEFAULT 'hello world';
    SELECT * FROM t1;
  }
} {1 100 {hello world} 2 300 {hello world}}





ifcapable schema_version {
  do_test alter3-4.4 {
    execsql {
      PRAGMA schema_version;
    }
  } {21}
}







>
>
>
>
>







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
} {}
do_test alter3-4.2 {
  execsql {
    ALTER TABLE t1 ADD c DEFAULT 'hello world';
    SELECT * FROM t1;
  }
} {1 100 {hello world} 2 300 {hello world}}
if {!$has_codec} {
  do_test alter3-4.3 {
    get_file_format
  } {3}
}
ifcapable schema_version {
  do_test alter3-4.4 {
    execsql {
      PRAGMA schema_version;
    }
  } {21}
}
252
253
254
255
256
257
258





259
260
261
262
263
264
265
  } {1 one {} 2 two {}}
  ifcapable schema_version {
    do_test alter3-5.4 {
      execsql {
        PRAGMA aux.schema_version;
      }
    } {31}





  }
  do_test alter3-5.6 {
    execsql {
      ALTER TABLE aux.t1 ADD COLUMN d DEFAULT 1000;
      SELECT sql FROM aux.sqlite_master;
    }
  } {{CREATE TABLE t1(a,b, c VARCHAR(128), d DEFAULT 1000)}}







>
>
>
>
>







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  } {1 one {} 2 two {}}
  ifcapable schema_version {
    do_test alter3-5.4 {
      execsql {
        PRAGMA aux.schema_version;
      }
    } {31}
  }
  if {!$has_codec} {
    do_test alter3-5.5 {
      list [get_file_format test2.db] [get_file_format]
    } {2 3}
  }
  do_test alter3-5.6 {
    execsql {
      ALTER TABLE aux.t1 ADD COLUMN d DEFAULT 1000;
      SELECT sql FROM aux.sqlite_master;
    }
  } {{CREATE TABLE t1(a,b, c VARCHAR(128), d DEFAULT 1000)}}
314
315
316
317
318
319
320



































321
322
323
324
325
326
327
      ALTER TABLE t1 ADD COLUMN c DEFAULT 'c';
      INSERT INTO t1(a, b) VALUES(3, 4);
      SELECT * FROM log;
    }
  } {b 1 2 a 1 2 b 3 4 a 3 4}
}





































# Ticket #1183 - Make sure adding columns to large tables does not cause
# memory corruption (as was the case before this bug was fixed).
do_test alter3-8.1 {
  execsql {
    CREATE TABLE t4(c1);
  }







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







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
      ALTER TABLE t1 ADD COLUMN c DEFAULT 'c';
      INSERT INTO t1(a, b) VALUES(3, 4);
      SELECT * FROM log;
    }
  } {b 1 2 a 1 2 b 3 4 a 3 4}
}

if {!$has_codec} {
  ifcapable vacuum {
    do_test alter3-7.1 {
      execsql {
        VACUUM;
      }
      get_file_format
    } {1}
    do_test alter3-7.2 {
      execsql {
        CREATE TABLE abc(a, b, c);
        ALTER TABLE abc ADD d DEFAULT NULL;
      }
      get_file_format
    } {2}
    do_test alter3-7.3 {
      execsql {
        ALTER TABLE abc ADD e DEFAULT 10;
      }
      get_file_format
    } {3}
    do_test alter3-7.4 {
      execsql {
        ALTER TABLE abc ADD f DEFAULT NULL;
      }
      get_file_format
    } {3}
    do_test alter3-7.5 {
      execsql {
        VACUUM;
      }
      get_file_format
    } {1}
  }
}

# Ticket #1183 - Make sure adding columns to large tables does not cause
# memory corruption (as was the case before this bug was fixed).
do_test alter3-8.1 {
  execsql {
    CREATE TABLE t4(c1);
  }
Changes to test/analyze3.test.
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  }
  execsql COMMIT
  execsql ANALYZE
} {}

do_eqp_test analyze3-1.1.2 {
  SELECT sum(y) FROM t1 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
do_eqp_test analyze3-1.1.3 {
  SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
do_test analyze3-1.1.4 {
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.1.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }







|


|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  }
  execsql COMMIT
  execsql ANALYZE
} {}

do_eqp_test analyze3-1.1.2 {
  SELECT sum(y) FROM t1 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~160 rows)}}
do_eqp_test analyze3-1.1.3 {
  SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~985 rows)}}
do_test analyze3-1.1.4 {
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.1.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
      CREATE INDEX i2 ON t2(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_eqp_test analyze3-1.2.2 {
  SELECT sum(y) FROM t2 WHERE x>1 AND x<2
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
do_eqp_test analyze3-1.2.3 {
  SELECT sum(y) FROM t2 WHERE x>0 AND x<99
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
do_test analyze3-1.2.4 {
  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
} {161 0 4760}
do_test analyze3-1.2.5 {
  set l [string range "12" 0 end]
  set u [string range "20" 0 end]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}







|


|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
      CREATE INDEX i2 ON t2(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_eqp_test analyze3-1.2.2 {
  SELECT sum(y) FROM t2 WHERE x>1 AND x<2
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~193 rows)}}
do_eqp_test analyze3-1.2.3 {
  SELECT sum(y) FROM t2 WHERE x>0 AND x<99
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~972 rows)}}
do_test analyze3-1.2.4 {
  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
} {161 0 4760}
do_test analyze3-1.2.5 {
  set l [string range "12" 0 end]
  set u [string range "20" 0 end]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
      CREATE INDEX i3 ON t3(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_eqp_test analyze3-1.3.2 {
  SELECT sum(y) FROM t3 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}
do_eqp_test analyze3-1.3.3 {
  SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}

do_test analyze3-1.3.4 {
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.3.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]







|


|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
      CREATE INDEX i3 ON t3(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_eqp_test analyze3-1.3.2 {
  SELECT sum(y) FROM t3 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~107 rows)}}
do_eqp_test analyze3-1.3.3 {
  SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~972 rows)}}

do_test analyze3-1.3.4 {
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.3.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
    execsql { INSERT INTO t1 VALUES($i, $t) }
  }
  execsql COMMIT
} {}
do_eqp_test analyze3-2.2 {
  SELECT count(a) FROM t1 WHERE b LIKE 'a%'
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}}
do_eqp_test analyze3-2.3 {
  SELECT count(a) FROM t1 WHERE b LIKE '%a'
} {0 0 0 {SCAN TABLE t1}}

do_test analyze3-2.4 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} {201 0 100}
do_test analyze3-2.5 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {1001 999 100}







|


|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
    execsql { INSERT INTO t1 VALUES($i, $t) }
  }
  execsql COMMIT
} {}
do_eqp_test analyze3-2.2 {
  SELECT count(a) FROM t1 WHERE b LIKE 'a%'
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?) (~31250 rows)}}
do_eqp_test analyze3-2.3 {
  SELECT count(a) FROM t1 WHERE b LIKE '%a'
} {0 0 0 {SCAN TABLE t1 (~500000 rows)}}

do_test analyze3-2.4 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} {201 0 100}
do_test analyze3-2.5 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {1001 999 100}
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
do_test analyze3-3.2.5 {
  set S [sqlite4_prepare db "SELECT * FROM t1 WHERE b=?" -1 dummy]
  test_for_recompile $S
} {0}
do_test analyze3-3.2.6 {
  sqlite4_bind_text $S 1 "abc" 3
  test_for_recompile $S
} {1}
do_test analyze3-3.2.7 {
  sqlite4_finalize $S
} {SQLITE4_OK}

do_test analyze3-3.4.1 {
  set S [sqlite4_prepare db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
  test_for_recompile $S







|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
do_test analyze3-3.2.5 {
  set S [sqlite4_prepare db "SELECT * FROM t1 WHERE b=?" -1 dummy]
  test_for_recompile $S
} {0}
do_test analyze3-3.2.6 {
  sqlite4_bind_text $S 1 "abc" 3
  test_for_recompile $S
} {0}
do_test analyze3-3.2.7 {
  sqlite4_finalize $S
} {SQLITE4_OK}

do_test analyze3-3.4.1 {
  set S [sqlite4_prepare db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
  test_for_recompile $S
Changes to test/analyze4.test.
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    INSERT INTO t1 SELECT a+32, b FROM t1;
    INSERT INTO t1 SELECT a+64, b FROM t1;
    ANALYZE;
  }

  # Should choose the t1a index since it is more specific than t1b.
  db eval {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=5 AND b IS NULL}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}

# Verify that the t1b index shows that it does not narrow down the
# search any at all.
#
do_test analyze4-1.1 {
  db eval {
    SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t1' ORDER BY idx;







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    INSERT INTO t1 SELECT a+32, b FROM t1;
    INSERT INTO t1 SELECT a+64, b FROM t1;
    ANALYZE;
  }

  # Should choose the t1a index since it is more specific than t1b.
  db eval {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=5 AND b IS NULL}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}

# Verify that the t1b index shows that it does not narrow down the
# search any at all.
#
do_test analyze4-1.1 {
  db eval {
    SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t1' ORDER BY idx;
Changes to test/analyze5.test.
24
25
26
27
28
29
30





31
32
33
34

35
36
37
38
39
40
41
42
43
44
45

set testprefix analyze5

proc eqp {sql {db db}} {
  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
}






proc alpha {blob} {
  set ret ""
  foreach c [split $blob {}] {
    if {[string is alpha $c]} {append ret $c}

  }
  return $ret
}
db func alpha alpha

unset -nocomplain i t u v w x y z
do_test analyze5-1.0 {
  db eval {CREATE TABLE t1(t,u,v TEXT COLLATE nocase,w,x,y,z)}
  for {set i 0} {$i < 1000} {incr i} {
    set y [expr {$i>=25 && $i<=50}]
    set z [expr {($i>=400) + ($i>=700) + ($i>=875)}]







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







24
25
26
27
28
29
30
31
32
33
34
35
36

37

38
39


40
41
42
43
44
45
46
47

set testprefix analyze5

proc eqp {sql {db db}} {
  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
}

# This command is registered as a user-defined function with the database
# handle. The blob passed as the only argument is a text-value encoded
# using the sqlite4 key-encoding with collation sequence BINARY. This
# command extracts and returns the text value.
#
proc decode {blob} {

  binary scan $blob c* vars

  binary format c* [lrange $vars 1 end-1]
}


db func decode decode

unset -nocomplain i t u v w x y z
do_test analyze5-1.0 {
  db eval {CREATE TABLE t1(t,u,v TEXT COLLATE nocase,w,x,y,z)}
  for {set i 0} {$i < 1000} {incr i} {
    set y [expr {$i>=25 && $i<=50}]
    set z [expr {($i>=400) + ($i>=700) + ($i>=875)}]
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    CREATE INDEX t1u ON t1(u);  -- text
    CREATE INDEX t1v ON t1(v);  -- mixed case text
    CREATE INDEX t1w ON t1(w);  -- integers 0, 1, 2 and a few NULLs
    CREATE INDEX t1x ON t1(x);  -- integers 1, 2, 3 and many NULLs
    CREATE INDEX t1y ON t1(y);  -- integers 0 and very few 1s
    CREATE INDEX t1z ON t1(z);  -- integers 0, 1, 2, and 3
    ANALYZE;
    SELECT alpha(sample) FROM sqlite_stat3 WHERE idx='t1u' ORDER BY nlt;
  }
} {alpha bravo charlie delta}

do_test analyze5-1.1 {
  db eval {
    SELECT DISTINCT alpha(lower(sample)) 
    FROM sqlite_stat3 WHERE idx='t1v'
    ORDER BY 1
  }
} {alpha bravo charlie delta}
do_test analyze5-1.2 {
  db eval {SELECT idx, count(*) FROM sqlite_stat3 GROUP BY 1 ORDER BY 1}
} {t1 24 t1t 4 t1u 4 t1v 4 t1w 4 t1x 4 t1y 2 t1z 4}

# Verify that range queries generate the correct row count estimates
#







|




<
<
|
|
<







62
63
64
65
66
67
68
69
70
71
72
73


74
75

76
77
78
79
80
81
82
    CREATE INDEX t1u ON t1(u);  -- text
    CREATE INDEX t1v ON t1(v);  -- mixed case text
    CREATE INDEX t1w ON t1(w);  -- integers 0, 1, 2 and a few NULLs
    CREATE INDEX t1x ON t1(x);  -- integers 1, 2, 3 and many NULLs
    CREATE INDEX t1y ON t1(y);  -- integers 0 and very few 1s
    CREATE INDEX t1z ON t1(z);  -- integers 0, 1, 2, and 3
    ANALYZE;
    SELECT decode(sample) FROM sqlite_stat3 WHERE idx='t1u' ORDER BY nlt;
  }
} {alpha bravo charlie delta}

do_test analyze5-1.1 {


  db eval {SELECT DISTINCT decode(sample) FROM sqlite_stat3 WHERE idx='t1v'
             ORDER BY 1}

} {alpha bravo charlie delta}
do_test analyze5-1.2 {
  db eval {SELECT idx, count(*) FROM sqlite_stat3 GROUP BY 1 ORDER BY 1}
} {t1 24 t1t 4 t1u 4 t1v 4 t1w 4 t1x 4 t1y 2 t1z 4}

# Verify that range queries generate the correct row count estimates
#
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  301  {y=1}                 t1y   26
  302  {y=0.1}               t1y    1

  400  {x IS NULL}           t1x  400

} {
  # Verify that the expected index is used with the expected row count
  # No longer valid due to an EXPLAIN QUERY PLAN output format change
  # do_test analyze5-1.${testid}a {
  #   set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
  #   set idx {}
  #   regexp {INDEX (t1.) } $x all idx
  #   regexp {~([0-9]+) rows} $x all nrow
  #   list $idx $nrow
  # } [list $index $rows]

  # Verify that the same result is achieved regardless of whether or not
  # the index is used
  do_test analyze5-1.${testid}b {
    set w2 [string map {y +y z +z} $where]
    set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\
                     ORDER BY +rowid"]







<
|
|
|
|
|
|
|







163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
  301  {y=1}                 t1y   26
  302  {y=0.1}               t1y    1

  400  {x IS NULL}           t1x  400

} {
  # Verify that the expected index is used with the expected row count

  do_test analyze5-1.${testid}a {
    set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
    set idx {}
    regexp {INDEX (t1.) } $x all idx
    regexp {~([0-9]+) rows} $x all nrow
    list $idx $nrow
  } [list $index $rows]

  # Verify that the same result is achieved regardless of whether or not
  # the index is used
  do_test analyze5-1.${testid}b {
    set w2 [string map {y +y z +z} $where]
    set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\
                     ORDER BY +rowid"]
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
  503  {x=1}                               t1x   1
  504  {x IS NOT NULL}                     t1x   2
  505  {+x IS NOT NULL}                     {} 500
  506  {upper(x) IS NOT NULL}               {} 500

} {
  # Verify that the expected index is used with the expected row count
  # No longer valid due to an EXPLAIN QUERY PLAN format change
  # do_test analyze5-1.${testid}a {
  #   set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
  #   set idx {}
  #   regexp {INDEX (t1.) } $x all idx
  #   regexp {~([0-9]+) rows} $x all nrow
  #   list $idx $nrow
  # } [list $index $rows]


  # Verify that the same result is achieved regardless of whether or not
  # the index is used
  do_test analyze5-1.${testid}b {
    set w2 [string map {y +y z +z} $where]
    set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\
                     ORDER BY +rowid"]







|
|
|
|
|
|
|
|
>







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  503  {x=1}                               t1x   1
  504  {x IS NOT NULL}                     t1x   2
  505  {+x IS NOT NULL}                     {} 500
  506  {upper(x) IS NOT NULL}               {} 500

} {
  # Verify that the expected index is used with the expected row count
if {$testid==50299} {breakpoint; set sqlite_where_trace 1}
  do_test analyze5-1.${testid}a {
    set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
    set idx {}
    regexp {INDEX (t1.) } $x all idx
    regexp {~([0-9]+) rows} $x all nrow
    list $idx $nrow
  } [list $index $rows]
if {$testid==50299} exit

  # Verify that the same result is achieved regardless of whether or not
  # the index is used
  do_test analyze5-1.${testid}b {
    set w2 [string map {y +y z +z} $where]
    set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\
                     ORDER BY +rowid"]
Changes to test/analyze6.test.
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
# The lowest cost plan is to scan CAT and for each integer there, do a single
# lookup of the first corresponding entry in EV then read off the equal values
# in EV.  (Prior to the 2011-03-04 enhancement to where.c, this query would
# have used EV for the outer loop instead of CAT - which was about 3x slower.)
#
do_test analyze6-1.1 {
  eqp {SELECT count(*) FROM ev, cat WHERE x=y}
} {0 0 1 {SCAN TABLE cat} 0 1 0 {SEARCH TABLE ev USING INDEX evy (y=?)}}

# The same plan is chosen regardless of the order of the tables in the
# FROM clause.
#
do_test analyze6-1.2 {
  eqp {SELECT count(*) FROM cat, ev WHERE x=y}
} {0 0 0 {SCAN TABLE cat} 0 1 1 {SEARCH TABLE ev USING INDEX evy (y=?)}}


# Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30
# If ANALYZE is run on an empty table, make sure indices are used
# on the table.
#
do_test analyze6-2.1 {
  execsql {
    CREATE TABLE t201(x INTEGER PRIMARY KEY, y UNIQUE, z);
    CREATE INDEX t201z ON t201(z);
    ANALYZE;
  }
  eqp {SELECT * FROM t201 WHERE z=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
do_test analyze6-2.2 {
  eqp {SELECT * FROM t201 WHERE y=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_t201_unique2 (y=?)}}
do_test analyze6-2.3 {
  eqp {SELECT * FROM t201 WHERE x=5}
} {0 0 0 {SEARCH TABLE t201 USING PRIMARY KEY (x=?)}}
do_test analyze6-2.4 {
  execsql {
    INSERT INTO t201 VALUES(1,2,3);
    ANALYZE t201;
  }
  eqp {SELECT * FROM t201 WHERE z=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
do_test analyze6-2.5 {
  eqp {SELECT * FROM t201 WHERE y=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_t201_unique2 (y=?)}}
do_test analyze6-2.6 {
  eqp {SELECT * FROM t201 WHERE x=5}
} {0 0 0 {SEARCH TABLE t201 USING PRIMARY KEY (x=?)}}
do_test analyze6-2.7 {
  execsql {
    INSERT INTO t201 VALUES(4,5,7);
    INSERT INTO t201 SELECT x+100, y+100, z+100 FROM t201;
    INSERT INTO t201 SELECT x+200, y+200, z+200 FROM t201;
    INSERT INTO t201 SELECT x+400, y+400, z+400 FROM t201;
    ANALYZE t201;
  }
  eqp {SELECT * FROM t201 WHERE z=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
do_test analyze6-2.8 {
  eqp {SELECT * FROM t201 WHERE y=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_t201_unique2 (y=?)}}
do_test analyze6-2.9 {
  eqp {SELECT * FROM t201 WHERE x=5}
} {0 0 0 {SEARCH TABLE t201 USING PRIMARY KEY (x=?)}}

finish_test







|






|













|


|


|






|


|


|









|


|


|


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
# The lowest cost plan is to scan CAT and for each integer there, do a single
# lookup of the first corresponding entry in EV then read off the equal values
# in EV.  (Prior to the 2011-03-04 enhancement to where.c, this query would
# have used EV for the outer loop instead of CAT - which was about 3x slower.)
#
do_test analyze6-1.1 {
  eqp {SELECT count(*) FROM ev, cat WHERE x=y}
} {0 0 1 {SCAN TABLE cat (~16 rows)} 0 1 0 {SEARCH TABLE ev USING INDEX evy (y=?) (~32 rows)}}

# The same plan is chosen regardless of the order of the tables in the
# FROM clause.
#
do_test analyze6-1.2 {
  eqp {SELECT count(*) FROM cat, ev WHERE x=y}
} {0 0 0 {SCAN TABLE cat (~16 rows)} 0 1 1 {SEARCH TABLE ev USING INDEX evy (y=?) (~32 rows)}}


# Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30
# If ANALYZE is run on an empty table, make sure indices are used
# on the table.
#
do_test analyze6-2.1 {
  execsql {
    CREATE TABLE t201(x INTEGER PRIMARY KEY, y UNIQUE, z);
    CREATE INDEX t201z ON t201(z);
    ANALYZE;
  }
  eqp {SELECT * FROM t201 WHERE z=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?) (~10 rows)}}
do_test analyze6-2.2 {
  eqp {SELECT * FROM t201 WHERE y=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_t201_unique2 (y=?) (~1 rows)}}
do_test analyze6-2.3 {
  eqp {SELECT * FROM t201 WHERE x=5}
} {0 0 0 {SEARCH TABLE t201 USING PRIMARY KEY (x=?) (~1 rows)}}
do_test analyze6-2.4 {
  execsql {
    INSERT INTO t201 VALUES(1,2,3);
    ANALYZE t201;
  }
  eqp {SELECT * FROM t201 WHERE z=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?) (~10 rows)}}
do_test analyze6-2.5 {
  eqp {SELECT * FROM t201 WHERE y=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_t201_unique2 (y=?) (~1 rows)}}
do_test analyze6-2.6 {
  eqp {SELECT * FROM t201 WHERE x=5}
} {0 0 0 {SEARCH TABLE t201 USING PRIMARY KEY (x=?) (~1 rows)}}
do_test analyze6-2.7 {
  execsql {
    INSERT INTO t201 VALUES(4,5,7);
    INSERT INTO t201 SELECT x+100, y+100, z+100 FROM t201;
    INSERT INTO t201 SELECT x+200, y+200, z+200 FROM t201;
    INSERT INTO t201 SELECT x+400, y+400, z+400 FROM t201;
    ANALYZE t201;
  }
  eqp {SELECT * FROM t201 WHERE z=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?) (~10 rows)}}
do_test analyze6-2.8 {
  eqp {SELECT * FROM t201 WHERE y=5}
} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_t201_unique2 (y=?) (~1 rows)}}
do_test analyze6-2.9 {
  eqp {SELECT * FROM t201 WHERE x=5}
} {0 0 0 {SEARCH TABLE t201 USING PRIMARY KEY (x=?) (~1 rows)}}

finish_test
Changes to test/analyze8.test.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#    values there are hundreds of entries.  The other has 10-20
#    entries per value.
#
# Verify that the query planner chooses the first index for the singleton
# entries and the second index for the others.
#
do_test 1.0 {
  prng_state_set 123456789009876543
  db eval {
    CREATE TABLE t1(a,b,c,d);
    CREATE INDEX t1a ON t1(a);
    CREATE INDEX t1b ON t1(b);
    CREATE INDEX t1c ON t1(c);
  }
  for {set i 0} {$i<1000} {incr i} {







<







33
34
35
36
37
38
39

40
41
42
43
44
45
46
#    values there are hundreds of entries.  The other has 10-20
#    entries per value.
#
# Verify that the query planner chooses the first index for the singleton
# entries and the second index for the others.
#
do_test 1.0 {

  db eval {
    CREATE TABLE t1(a,b,c,d);
    CREATE INDEX t1a ON t1(a);
    CREATE INDEX t1b ON t1(b);
    CREATE INDEX t1c ON t1(c);
  }
  for {set i 0} {$i<1000} {incr i} {
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
# with a==100.  And so for those cases, choose the t1b index.
#
# Buf ro a==99 and a==101, there are far fewer rows so choose
# the t1a index.
#
do_test 1.1 {
  eqp {SELECT * FROM t1 WHERE a=100 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
do_test 1.2 {
  eqp {SELECT * FROM t1 WHERE a=99 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
do_test 1.3 {
  eqp {SELECT * FROM t1 WHERE a=101 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
do_test 1.4 {
  eqp {SELECT * FROM t1 WHERE a=100 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
do_test 1.5 {
  eqp {SELECT * FROM t1 WHERE a=99 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
do_test 1.6 {
  eqp {SELECT * FROM t1 WHERE a=101 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
do_test 2.1 {
  eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}

# There are many more values of c between 0 and 100000 than there are
# between 800000 and 900000.  So t1c is more selective for the latter
# range.
#
do_test 3.1 {
  eqp {SELECT * FROM t1 WHERE b BETWEEN 50 AND 54 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
do_test 3.2 {
  eqp {SELECT * FROM t1
       WHERE b BETWEEN 50 AND 54 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
do_test 3.3 {
  eqp {SELECT * FROM t1 WHERE a=100 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
do_test 3.4 {
  eqp {SELECT * FROM t1
       WHERE a=100 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}

finish_test







|


|


|


|


|


|


|







|



|


|



|


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
# with a==100.  And so for those cases, choose the t1b index.
#
# Buf ro a==99 and a==101, there are far fewer rows so choose
# the t1a index.
#
do_test 1.1 {
  eqp {SELECT * FROM t1 WHERE a=100 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}}
do_test 1.2 {
  eqp {SELECT * FROM t1 WHERE a=99 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 1.3 {
  eqp {SELECT * FROM t1 WHERE a=101 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 1.4 {
  eqp {SELECT * FROM t1 WHERE a=100 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}}
do_test 1.5 {
  eqp {SELECT * FROM t1 WHERE a=99 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 1.6 {
  eqp {SELECT * FROM t1 WHERE a=101 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 2.1 {
  eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?) (~2 rows)}}

# There are many more values of c between 0 and 100000 than there are
# between 800000 and 900000.  So t1c is more selective for the latter
# range.
#
do_test 3.1 {
  eqp {SELECT * FROM t1 WHERE b BETWEEN 50 AND 54 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?) (~6 rows)}}
do_test 3.2 {
  eqp {SELECT * FROM t1
       WHERE b BETWEEN 50 AND 54 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?) (~4 rows)}}
do_test 3.3 {
  eqp {SELECT * FROM t1 WHERE a=100 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~63 rows)}}
do_test 3.4 {
  eqp {SELECT * FROM t1
       WHERE a=100 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?) (~2 rows)}}

finish_test
Changes to test/attach.test.
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    ATTACH 'test.db' AS db7;
    ATTACH 'test.db' AS db8;
    ATTACH 'test.db' AS db9;
  }
} {}
proc db_list {db} {
  set list {}
  foreach {idx name} [execsql {PRAGMA database_list} $db] {
    lappend list $idx $name
  }
  return $list
}
ifcapable schema_pragmas {
do_test attach-1.11b {
  db_list db







|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    ATTACH 'test.db' AS db7;
    ATTACH 'test.db' AS db8;
    ATTACH 'test.db' AS db9;
  }
} {}
proc db_list {db} {
  set list {}
  foreach {idx name file} [execsql {PRAGMA database_list} $db] {
    lappend list $idx $name
  }
  return $list
}
ifcapable schema_pragmas {
do_test attach-1.11b {
  db_list db
853
854
855
856
857
858
859
860
861
862
    COMMIT;
    SELECT name FROM noname.sqlite_master;
    SELECT name FROM inmem.sqlite_master;
  }
} {noname inmem}
do_test attach-10.2 {
  execsql { PRAGMA database_list }
} {0 main 2 noname 3 inmem} 

finish_test







|


853
854
855
856
857
858
859
860
861
862
    COMMIT;
    SELECT name FROM noname.sqlite_master;
    SELECT name FROM inmem.sqlite_master;
  }
} {noname inmem}
do_test attach-10.2 {
  execsql { PRAGMA database_list }
} {0 main filename 2 noname filename 3 inmem filename}

finish_test
Changes to test/attach3.test.
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  }
} {}
do_test attach3-3.2 {
  execsql {
    CREATE INDEX aux.i1 on t3(e);
    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
  }
} "index i1 t3 6 {CREATE INDEX i1 on t3(e)}"
do_test attach3-3.3 {
  execsql {
    DROP INDEX i1;
    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
  }
} {}








|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  }
} {}
do_test attach3-3.2 {
  execsql {
    CREATE INDEX aux.i1 on t3(e);
    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
  }
} "index i1 t3 [expr $AUTOVACUUM?6:5] {CREATE INDEX i1 on t3(e)}"
do_test attach3-3.3 {
  execsql {
    DROP INDEX i1;
    SELECT * FROM aux.sqlite_master WHERE name = 'i1';
  }
} {}

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
} {}
} ;# ifcapable view

ifcapable {trigger} {
# Create a trigger in the auxilary database.
do_test attach3-7.1 {
  execsql {
    CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 WHEN new.f<30 BEGIN
      INSERT INTO t3 VALUES(new.e*2, new.f*2);
    END;
  }
} {}
do_test attach3-7.2 {
  execsql {
    DELETE FROM t3;
    INSERT INTO t3 VALUES(10, 20);
    SELECT * FROM t3;
  }
} {10 20 20 40}
do_test attach3-7.3 {
  execsql {
    SELECT * FROM aux.sqlite_master WHERE name = 'tr1';
  }
} {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 WHEN new.f<30 BEGIN
      INSERT INTO t3 VALUES(new.e*2, new.f*2);
    END}}

# Drop the trigger 
do_test attach3-8.1 {
  execsql {
    DROP TRIGGER aux.tr1;







|











|



|







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
} {}
} ;# ifcapable view

ifcapable {trigger} {
# Create a trigger in the auxilary database.
do_test attach3-7.1 {
  execsql {
    CREATE TRIGGER aux.tr1 AFTER INSERT ON t3 BEGIN
      INSERT INTO t3 VALUES(new.e*2, new.f*2);
    END;
  }
} {}
do_test attach3-7.2 {
  execsql {
    DELETE FROM t3;
    INSERT INTO t3 VALUES(10, 20);
    SELECT * FROM t3;
  }
} {10 20 20 40}
do_test attach3-5.3 {
  execsql {
    SELECT * FROM aux.sqlite_master WHERE name = 'tr1';
  }
} {trigger tr1 t3 0 {CREATE TRIGGER tr1 AFTER INSERT ON t3 BEGIN
      INSERT INTO t3 VALUES(new.e*2, new.f*2);
    END}}

# Drop the trigger 
do_test attach3-8.1 {
  execsql {
    DROP TRIGGER aux.tr1;
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# Return a list of attached databases
#
proc db_list {} {
  set x [execsql {
    PRAGMA database_list;
  }]
  set y {}
  foreach {n id} $x {lappend y $id}
  return $y
}

ifcapable schema_pragmas&&tempdb {

ifcapable !trigger {
  execsql {create temp table dummy(dummy)}







|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# Return a list of attached databases
#
proc db_list {} {
  set x [execsql {
    PRAGMA database_list;
  }]
  set y {}
  foreach {n id file} $x {lappend y $id}
  return $y
}

ifcapable schema_pragmas&&tempdb {

ifcapable !trigger {
  execsql {create temp table dummy(dummy)}
Changes to test/attach4.test.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  sqlite4 db test.db
  
  foreach {name f} $files {
    if {$name == "main"} continue
    execsql "ATTACH '$f' AS $name"
  }

  db eval {PRAGMA database_list} { lappend L $name }
  foreach {n f} $files { lappend K $n }

  string compare $L $K
} 0

do_catchsql_test 1.2.2 {
  ATTACH 'x.db' AS next;
} [list 1 "too many attached databases - max $SQLITE4_MAX_ATTACHED"]

do_test 1.3 {
  execsql BEGIN;







|
|
|
|
|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  sqlite4 db test.db
  
  foreach {name f} $files {
    if {$name == "main"} continue
    execsql "ATTACH '$f' AS $name"
  }

  db eval {PRAGMA database_list} {
    lappend L $name [file tail $file]
  }
  set L
} $files

do_catchsql_test 1.2.2 {
  ATTACH 'x.db' AS next;
} [list 1 "too many attached databases - max $SQLITE4_MAX_ATTACHED"]

do_test 1.3 {
  execsql BEGIN;
67
68
69
70
71
72
73
74

75









76

77


78
79
80
81
82
83
84
  set L [list]
  foreach {name f} $files {
    lappend L $name [execsql "SELECT x FROM $name.tbl"]
  }
  set L
} $files



foreach {name f} $files {









  execsql "UPDATE $name.tbl SET x = '$name'"

}


do_test 1.6 {
  set L [list]
  foreach {name f} $files {
    lappend L [execsql "SELECT x FROM $name.tbl"] $f
  }
  set L
} $files







|
>

>
>
>
>
>
>
>
>
>
|
>

>
>







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
  set L [list]
  foreach {name f} $files {
    lappend L $name [execsql "SELECT x FROM $name.tbl"]
  }
  set L
} $files

set L [list]
set S ""
foreach {name f} $files {
  if {[permutation] == "journaltest"} {
    set mode delete
  } else {
    set mode wal
  }
  ifcapable !wal { set mode delete }
  lappend L $mode
  append S "
    PRAGMA $name.journal_mode = WAL;
    UPDATE $name.tbl SET x = '$name';
  "
}
do_execsql_test 1.5 $S $L

do_test 1.6 {
  set L [list]
  foreach {name f} $files {
    lappend L [execsql "SELECT x FROM $name.tbl"] $f
  }
  set L
} $files
Changes to test/auth.test.
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
    catchsql {
      DETACH DATABASE test1;
    }
  } {0 {}}
  ifcapable tempdb {
    ifcapable schema_pragmas {
    do_test auth-1.260 {
      lindex [execsql {PRAGMA database_list}] 5
    } {test1}
    } ;# ifcapable schema_pragmas
    do_test auth-1.261 {
      proc auth {code arg1 arg2 arg3 arg4} {
        if {$code=="SQLITE4_DETACH"} {
          set ::authargs [list $arg1 $arg2 $arg3 $arg4]
          return SQLITE4_DENY
        }
        return SQLITE4_OK
      }
      catchsql {
        DETACH DATABASE test1;
      }
    } {1 {not authorized}}
    ifcapable schema_pragmas {
    do_test auth-1.262 {
      lindex [execsql {PRAGMA database_list}] 5
    } {test1}
    } ;# ifcapable schema_pragmas
    db authorizer {}
    execsql {DETACH DATABASE test1}
    db authorizer ::auth
    
    # Authorization for ALTER TABLE. These tests are omitted if the library







|
















|







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
    catchsql {
      DETACH DATABASE test1;
    }
  } {0 {}}
  ifcapable tempdb {
    ifcapable schema_pragmas {
    do_test auth-1.260 {
      lindex [execsql {PRAGMA database_list}] 7
    } {test1}
    } ;# ifcapable schema_pragmas
    do_test auth-1.261 {
      proc auth {code arg1 arg2 arg3 arg4} {
        if {$code=="SQLITE4_DETACH"} {
          set ::authargs [list $arg1 $arg2 $arg3 $arg4]
          return SQLITE4_DENY
        }
        return SQLITE4_OK
      }
      catchsql {
        DETACH DATABASE test1;
      }
    } {1 {not authorized}}
    ifcapable schema_pragmas {
    do_test auth-1.262 {
      lindex [execsql {PRAGMA database_list}] 7
    } {test1}
    } ;# ifcapable schema_pragmas
    db authorizer {}
    execsql {DETACH DATABASE test1}
    db authorizer ::auth
    
    # Authorization for ALTER TABLE. These tests are omitted if the library
Changes to test/autoindex1.test.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# If the library is not compiled with automatic index support then
# skip all tests in this file.
#
ifcapable {!autoindex} {
  finish_test
  return
}

# Setup for logging 
#db close
#sqlite4_shutdown
#test_sqlite4_log [list lappend ::log]
#set ::log [list]
#sqlite4 db test.db


# With automatic index turned off, we do a full scan of the T2 table
do_test autoindex1-100 {
  db eval {
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,11);
    INSERT INTO t1 VALUES(2,22);







<
<
<
<
<
<
<
<







18
19
20
21
22
23
24








25
26
27
28
29
30
31
# If the library is not compiled with automatic index support then
# skip all tests in this file.
#
ifcapable {!autoindex} {
  finish_test
  return
}









# With automatic index turned off, we do a full scan of the T2 table
do_test autoindex1-100 {
  db eval {
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,11);
    INSERT INTO t1 VALUES(2,22);
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
} {63}
do_test autoindex1-102 {
  db status autoindex
} {0}

# With autoindex turned on, we build an index once and then use that index
# to find T2 values.

do_test autoindex1-110 {
  db eval {
    PRAGMA automatic_index=ON;
    SELECT b, d FROM t1 JOIN t2 ON a=c ORDER BY b;
  }
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-111 {
  db status step
} {7}
do_test autoindex1-112 {
  db status autoindex
} {7}
#do_test autoindex1-113 {
  #set ::log
#} {SQLITE_WARNING_AUTOINDEX {automatic index on t2(c)}}

#db close
#sqlite4_shutdown
#test_sqlite4_log
#sqlite4_initialize
#sqlite4 db test.db

# The same test as above, but this time the T2 query is a subquery rather
# than a join.
do_test autoindex1-200 {
  db eval {
    PRAGMA automatic_index=OFF;
    SELECT b, (SELECT d FROM t2 WHERE c=a) FROM t1;
  }
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-201 {
  db status step
} {35}
do_test autoindex1-202 {
  db status autoindex
} {0}
do_test autoindex1-210 {
  db eval {
    PRAGMA automatic_index=ON;
    ANALYZE;
    UPDATE sqlite_stat1 SET stat='10000' WHERE tbl='t1';
    ANALYZE sqlite_master;
    SELECT b, (SELECT d FROM t2 WHERE c=a) FROM t1;
  }
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-211 {
  db status step
} {7}
do_test autoindex1-212 {
  db status autoindex
} {7}


# Modify the second table of the join while the join is in progress
#
do_execsql_test autoindex1-299 {
  UPDATE sqlite_stat1 SET stat='10000' WHERE tbl='t2';
  ANALYZE sqlite_master;
  EXPLAIN QUERY PLAN
  SELECT b, d FROM t1 CROSS JOIN t2 ON (c=a);
} {/AUTOMATIC COVERING INDEX/}
do_test autoindex1-300 {
  set r {}
  db eval {SELECT b, d FROM t1 CROSS JOIN t2 ON (c=a)} {
    lappend r $b $d
    db eval {UPDATE t2 SET d=d+1}
  }
  set r
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-310 {
  db eval {SELECT d FROM t2 ORDER BY d}







>












<
<
<
<
<
<
<
<
<


















<
<
<













<
<
<
<
<
<


|







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
} {63}
do_test autoindex1-102 {
  db status autoindex
} {0}

# With autoindex turned on, we build an index once and then use that index
# to find T2 values.
#
do_test autoindex1-110 {
  db eval {
    PRAGMA automatic_index=ON;
    SELECT b, d FROM t1 JOIN t2 ON a=c ORDER BY b;
  }
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-111 {
  db status step
} {7}
do_test autoindex1-112 {
  db status autoindex
} {7}










# The same test as above, but this time the T2 query is a subquery rather
# than a join.
do_test autoindex1-200 {
  db eval {
    PRAGMA automatic_index=OFF;
    SELECT b, (SELECT d FROM t2 WHERE c=a) FROM t1;
  }
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-201 {
  db status step
} {35}
do_test autoindex1-202 {
  db status autoindex
} {0}
do_test autoindex1-210 {
  db eval {
    PRAGMA automatic_index=ON;



    SELECT b, (SELECT d FROM t2 WHERE c=a) FROM t1;
  }
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-211 {
  db status step
} {7}
do_test autoindex1-212 {
  db status autoindex
} {7}


# Modify the second table of the join while the join is in progress
#






do_test autoindex1-300 {
  set r {}
  db eval {SELECT b, d FROM t1 JOIN t2 ON (c=a)} {
    lappend r $b $d
    db eval {UPDATE t2 SET d=d+1}
  }
  set r
} {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
do_test autoindex1-310 {
  db eval {SELECT d FROM t2 ORDER BY d}
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
# Ticket [8011086c85c6c404014c947fcf3eb9f42b184a0d] from 2010-07-08
# Make sure automatic indices are not created for the RHS of an IN expression
# that is not a correlated subquery.
#
do_execsql_test autoindex1-500 {
  CREATE TABLE t501(a INTEGER PRIMARY KEY, b);
  CREATE TABLE t502(x INTEGER PRIMARY KEY, y);
  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t501','t501','1000000');
  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t502','t502','1000');
  ANALYZE sqlite_master;
  EXPLAIN QUERY PLAN
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
} {
  0 0 0 {SEARCH TABLE t501 USING PRIMARY KEY (a=?)} 
  0 0 0 {EXECUTE LIST SUBQUERY 1} 
  1 0 0 {SCAN TABLE t502}
}
do_execsql_test autoindex1-501 {
  EXPLAIN QUERY PLAN
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  0 0 0 {SCAN TABLE t501} 
  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
  1 0 0 {SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)}
}
do_execsql_test autoindex1-502 {
  EXPLAIN QUERY PLAN
  SELECT b FROM t501
   WHERE t501.a=123
     AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  0 0 0 {SEARCH TABLE t501 USING PRIMARY KEY (a=?)}
  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
  1 0 0 {SCAN TABLE t502}
}


# The following code checks a performance regression reported on the
# mailing list on 2010-10-19.  The problem is that the nRowEst field
# of ephermeral tables was not being initialized correctly and so no
# automatic index was being created for the emphemeral table when it was







<
<
<




|

|






|

|







|

|







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
# Ticket [8011086c85c6c404014c947fcf3eb9f42b184a0d] from 2010-07-08
# Make sure automatic indices are not created for the RHS of an IN expression
# that is not a correlated subquery.
#
do_execsql_test autoindex1-500 {
  CREATE TABLE t501(a INTEGER PRIMARY KEY, b);
  CREATE TABLE t502(x INTEGER PRIMARY KEY, y);



  EXPLAIN QUERY PLAN
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
} {
  0 0 0 {SEARCH TABLE t501 USING PRIMARY KEY (a=?) (~25 rows)} 
  0 0 0 {EXECUTE LIST SUBQUERY 1} 
  1 0 0 {SCAN TABLE t502 (~100000 rows)}
}
do_execsql_test autoindex1-501 {
  EXPLAIN QUERY PLAN
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  0 0 0 {SCAN TABLE t501 (~500000 rows)} 
  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
  1 0 0 {SEARCH TABLE t502 USING AUTOMATIC INDEX (y=?) (~7 rows)}
}
do_execsql_test autoindex1-502 {
  EXPLAIN QUERY PLAN
  SELECT b FROM t501
   WHERE t501.a=123
     AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  0 0 0 {SEARCH TABLE t501 USING PRIMARY KEY (a=?) (~1 rows)} 
  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
  1 0 0 {SCAN TABLE t502 (~100000 rows)}
}


# The following code checks a performance regression reported on the
# mailing list on 2010-10-19.  The problem is that the nRowEst field
# of ephermeral tables was not being initialized correctly and so no
# automatic index was being created for the emphemeral table when it was
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
           WHERE prev.flock_no = later.flock_no
           AND later.owner_change_date > prev.owner_change_date
           AND later.owner_change_date <= s.date_of_registration||' 00:00:00')
       ) y ON x.sheep_no = y.sheep_no
   WHERE y.sheep_no IS NULL
   ORDER BY x.registering_flock;
} {
  1 0 0 {SCAN TABLE sheep AS s}
  1 1 1 {SEARCH TABLE flock_owner AS prev USING INDEX sqlite_flock_owner_unique2 (flock_no=? AND owner_change_date<?)} 
  1 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
  2 0 0 {SEARCH TABLE flock_owner AS later USING INDEX sqlite_flock_owner_unique2 (flock_no=? AND owner_change_date>? AND owner_change_date<?)} 
  0 0 0 {SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index} 
  0 1 1 {SEARCH SUBQUERY 1 AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)}
}


do_execsql_test autoindex1-700 {
  CREATE TABLE t5(a, b, c);
  EXPLAIN QUERY PLAN SELECT a FROM t5 WHERE b=10 ORDER BY c;
} {
  0 0 0 {SCAN TABLE t5} 
  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}

# The following checks a performance issue reported on the sqlite-dev
# mailing list on 2013-01-10
#
do_execsql_test autoindex1-800 {
  CREATE TABLE accounts(
    _id INTEGER PRIMARY KEY AUTOINCREMENT,
    account_name TEXT,
    account_type TEXT,
    data_set TEXT
  );
  CREATE TABLE data(
    _id INTEGER PRIMARY KEY AUTOINCREMENT,
    package_id INTEGER REFERENCES package(_id),
    mimetype_id INTEGER REFERENCES mimetype(_id) NOT NULL,
    raw_contact_id INTEGER REFERENCES raw_contacts(_id) NOT NULL,
    is_read_only INTEGER NOT NULL DEFAULT 0,
    is_primary INTEGER NOT NULL DEFAULT 0,
    is_super_primary INTEGER NOT NULL DEFAULT 0,
    data_version INTEGER NOT NULL DEFAULT 0,
    data1 TEXT,
    data2 TEXT,
    data3 TEXT,
    data4 TEXT,
    data5 TEXT,
    data6 TEXT,
    data7 TEXT,
    data8 TEXT,
    data9 TEXT,
    data10 TEXT,
    data11 TEXT,
    data12 TEXT,
    data13 TEXT,
    data14 TEXT,
    data15 TEXT,
    data_sync1 TEXT,
    data_sync2 TEXT,
    data_sync3 TEXT,
    data_sync4 TEXT 
  );
  CREATE TABLE mimetypes(
    _id INTEGER PRIMARY KEY AUTOINCREMENT,
    mimetype TEXT NOT NULL
  );
  CREATE TABLE raw_contacts(
    _id INTEGER PRIMARY KEY AUTOINCREMENT,
    account_id INTEGER REFERENCES accounts(_id),
    sourceid TEXT,
    raw_contact_is_read_only INTEGER NOT NULL DEFAULT 0,
    version INTEGER NOT NULL DEFAULT 1,
    dirty INTEGER NOT NULL DEFAULT 0,
    deleted INTEGER NOT NULL DEFAULT 0,
    contact_id INTEGER REFERENCES contacts(_id),
    aggregation_mode INTEGER NOT NULL DEFAULT 0,
    aggregation_needed INTEGER NOT NULL DEFAULT 1,
    custom_ringtone TEXT,
    send_to_voicemail INTEGER NOT NULL DEFAULT 0,
    times_contacted INTEGER NOT NULL DEFAULT 0,
    last_time_contacted INTEGER,
    starred INTEGER NOT NULL DEFAULT 0,
    display_name TEXT,
    display_name_alt TEXT,
    display_name_source INTEGER NOT NULL DEFAULT 0,
    phonetic_name TEXT,
    phonetic_name_style TEXT,
    sort_key TEXT,
    sort_key_alt TEXT,
    name_verified INTEGER NOT NULL DEFAULT 0,
    sync1 TEXT,
    sync2 TEXT,
    sync3 TEXT,
    sync4 TEXT,
    sync_uid TEXT,
    sync_version INTEGER NOT NULL DEFAULT 1,
    has_calendar_event INTEGER NOT NULL DEFAULT 0,
    modified_time INTEGER,
    is_restricted INTEGER DEFAULT 0,
    yp_source TEXT,
    method_selected INTEGER DEFAULT 0,
    custom_vibration_type INTEGER DEFAULT 0,
    custom_ringtone_path TEXT,
    message_notification TEXT,
    message_notification_path TEXT
  );
  CREATE INDEX data_mimetype_data1_index ON data (mimetype_id,data1);
  CREATE INDEX data_raw_contact_id ON data (raw_contact_id);
  CREATE UNIQUE INDEX mime_type ON mimetypes (mimetype);
  CREATE INDEX raw_contact_sort_key1_index ON raw_contacts (sort_key);
  CREATE INDEX raw_contact_sort_key2_index ON raw_contacts (sort_key_alt);
  CREATE INDEX raw_contacts_contact_id_index ON raw_contacts (contact_id);
  CREATE INDEX raw_contacts_source_id_account_id_index
      ON raw_contacts (sourceid, account_id);
  ANALYZE sqlite_master;
  INSERT INTO sqlite_stat1
     VALUES('raw_contacts','raw_contact_sort_key2_index','1600 4');
  INSERT INTO sqlite_stat1
     VALUES('raw_contacts','raw_contact_sort_key1_index','1600 4');
  INSERT INTO sqlite_stat1
     VALUES('raw_contacts','raw_contacts_source_id_account_id_index',
            '1600 1600 1600');
  INSERT INTO sqlite_stat1
     VALUES('raw_contacts','raw_contacts_contact_id_index','1600 1');
  INSERT INTO sqlite_stat1 VALUES('mimetypes','mime_type','12 1');
  INSERT INTO sqlite_stat1 VALUES('mimetypes','mimetypes','12');
  INSERT INTO sqlite_stat1 VALUES('raw_contacts','raw_contacts','1600');
  INSERT INTO sqlite_stat1
     VALUES('data','data_mimetype_data1_index','9819 2455 3');
  INSERT INTO sqlite_stat1 VALUES('data','data_raw_contact_id','9819 7');
  INSERT INTO sqlite_stat1 VALUES('accounts','accounts','1');
  DROP TABLE IF EXISTS sqlite_stat3;
  ANALYZE sqlite_master;
  EXPLAIN QUERY PLAN
  SELECT * FROM 
        data JOIN mimetypes ON (data.mimetype_id=mimetypes._id) 
             JOIN raw_contacts ON (data.raw_contact_id=raw_contacts._id) 
             JOIN accounts ON (raw_contacts.account_id=accounts._id)
   WHERE mimetype_id=10 AND data14 IS NOT NULL;
} {/SEARCH TABLE data .*SEARCH TABLE raw_contacts/}
do_execsql_test autoindex1-801 {
  EXPLAIN QUERY PLAN
  SELECT * FROM 
        data JOIN mimetypes ON (data.mimetype_id=mimetypes._id) 
             JOIN raw_contacts ON (data.raw_contact_id=raw_contacts._id) 
             JOIN accounts ON (raw_contacts.account_id=accounts._id)
   WHERE mimetypes._id=10 AND data14 IS NOT NULL;
} {/SEARCH TABLE data .*SEARCH TABLE raw_contacts/}

finish_test







|
|
|
|
|
|







|



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

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
           WHERE prev.flock_no = later.flock_no
           AND later.owner_change_date > prev.owner_change_date
           AND later.owner_change_date <= s.date_of_registration||' 00:00:00')
       ) y ON x.sheep_no = y.sheep_no
   WHERE y.sheep_no IS NULL
   ORDER BY x.registering_flock;
} {
  1 0 0 {SCAN TABLE sheep AS s (~1000000 rows)} 
  1 1 1 {SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_2 (flock_no=? AND owner_change_date<?) (~2 rows)} 
  1 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2} 
  2 0 0 {SEARCH TABLE flock_owner AS later USING INDEX sqlite_autoindex_flock_owner_2 (flock_no=? AND owner_change_date>? AND owner_change_date<?) (~1 rows)} 
  0 0 0 {SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index (~1000000 rows)} 
  0 1 1 {SEARCH SUBQUERY 1 AS y USING AUTOMATIC INDEX (sheep_no=?) (~8 rows)}
}


do_execsql_test autoindex1-700 {
  CREATE TABLE t5(a, b, c);
  EXPLAIN QUERY PLAN SELECT a FROM t5 WHERE b=10 ORDER BY c;
} {
  0 0 0 {SCAN TABLE t5 (~100000 rows)} 
  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}































































































































finish_test
Changes to test/badutf2.test.
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
  db close
  forcedelete test.db
  sqlite4 db test.db
  db eval "PRAGMA encoding = 'UTF-8'"
} {}

do_test badutf2-4.0 {
  set S [sqlite4_prepare db "SELECT ?" -1 dummy]
  expr {$S==""}
} {0}
        
foreach { i len uval xstr ustr u2u } {
1 1 00     \x00         {}        {}
2 1 01     \x01         "\\u0001" 01
3 1 3f     \x3F         "\\u003F" 3f
4 1 7f     \x7F         "\\u007F" 7f
5 1 80     \x80         "\\u0080" c280
6 1 c3bf   \xFF         "\\u00FF" c3bf
7 3 efbfbd \xEF\xBF\xBD "\\uFFFD" {}
} {

  set hstr [ utf8_to_hstr $uval ]

  ifcapable bloblit {
    if {$hstr != "%00"} {
      do_test badutf2-2.1.$i {







|
|





|
|
|
|
|







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
  db close
  forcedelete test.db
  sqlite4 db test.db
  db eval "PRAGMA encoding = 'UTF-8'"
} {}

do_test badutf2-4.0 {
  set S [sqlite4_prepare_v2 db "SELECT ?" -1 dummy]
  sqlite4_expired $S
} {0}
        
foreach { i len uval xstr ustr u2u } {
1 1 00     \x00         {}        {}
2 1 01     \x01         "\\u0001" 01
3 1 3F     \x3F         "\\u003F" 3F
4 1 7F     \x7F         "\\u007F" 7F
5 1 80     \x80         "\\u0080" C280
6 1 C3BF   \xFF         "\\u00FF" C3BF
7 3 EFBFBD \xEF\xBF\xBD "\\uFFFD" {}
} {

  set hstr [ utf8_to_hstr $uval ]

  ifcapable bloblit {
    if {$hstr != "%00"} {
      do_test badutf2-2.1.$i {
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    sqlite4_bind_text $S 1 $xstr $len
    sqlite4_step $S
    utf8_to_ustr2 [ sqlite4_column_text $S 0 ]
  } $ustr

  ifcapable debug {
    do_test badutf2-5.1.$i {
      string tolower [utf8_to_utf8 $uval]
    } $u2u
  }

}

do_test badutf2-4.2 {
  sqlite4_finalize $S
} {SQLITE4_OK}


finish_test







|











103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    sqlite4_bind_text $S 1 $xstr $len
    sqlite4_step $S
    utf8_to_ustr2 [ sqlite4_column_text $S 0 ]
  } $ustr

  ifcapable debug {
    do_test badutf2-5.1.$i {
      utf8_to_utf8 $uval
    } $u2u
  }

}

do_test badutf2-4.2 {
  sqlite4_finalize $S
} {SQLITE4_OK}


finish_test
Changes to test/between.test.
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
    CREATE INDEX i1zyx ON t1(z,y,x);
    COMMIT;
  }
} {}

# This procedure executes the SQL.  Then it appends to the result the
# "sort" or "nosort" keyword depending on whether or not any sorting
# is done.  Then it appends the names of the table and index used.
#
proc queryplan {sql} {
  set ::sqlite_sort_count 0
  set data [execsql $sql]
  if {$::sqlite_sort_count} {set x sort} {set x nosort}
  lappend data $x
  set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
  # puts eqp=$eqp
  foreach {a b c x} $eqp {
    if {[regexp { TABLE (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \
        $x all as tab idx]} {
      lappend data $tab $idx
    } elseif {[regexp { TABLE (\w+ AS )?(\w+)\y} $x all as tab]} {
      lappend data $tab *
    }
  }
  return $data   
}

do_test between-1.1.1 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 5 AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 i1w}
do_test between-1.1.2 {
  queryplan {
    SELECT * FROM t1 WHERE +w BETWEEN 5 AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 *}
do_test between-1.2.1 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 5 AND 65-y ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 i1w}
do_test between-1.2.2 {
  queryplan {
    SELECT * FROM t1 WHERE +w BETWEEN 5 AND 65-y ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 *}
do_test between-1.3.1 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 41-y AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 i1w}
do_test between-1.3.2 {
  queryplan {
    SELECT * FROM t1 WHERE +w BETWEEN 41-y AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 *}
do_test between-1.4 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 41-y AND 65-y ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 *}
do_test between-1.5.1 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN y AND z ORDER BY +w
  }
} {4 2 25 27 sort t1 i1zyx}
do_test between-1.5.2 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN +y AND z ORDER BY +w
  }
} {4 2 25 27 sort t1 i1zyx}
do_test between-1.5.3 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN y AND +z ORDER BY +w
  }
} {4 2 25 27 sort t1 *}


finish_test







|






<
<
<
<
<
<
<
<
<
<
|











|









|









|




|














|



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
    CREATE INDEX i1zyx ON t1(z,y,x);
    COMMIT;
  }
} {}

# This procedure executes the SQL.  Then it appends to the result the
# "sort" or "nosort" keyword depending on whether or not any sorting
# is done.  Then it appends the ::sqlite_query_plan variable.
#
proc queryplan {sql} {
  set ::sqlite_sort_count 0
  set data [execsql $sql]
  if {$::sqlite_sort_count} {set x sort} {set x nosort}
  lappend data $x










  return [concat $data $::sqlite_query_plan]
}

do_test between-1.1.1 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 5 AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 i1w}
do_test between-1.1.2 {
  queryplan {
    SELECT * FROM t1 WHERE +w BETWEEN 5 AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 {}}
do_test between-1.2.1 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 5 AND 65-y ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 i1w}
do_test between-1.2.2 {
  queryplan {
    SELECT * FROM t1 WHERE +w BETWEEN 5 AND 65-y ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 {}}
do_test between-1.3.1 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 41-y AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 i1w}
do_test between-1.3.2 {
  queryplan {
    SELECT * FROM t1 WHERE +w BETWEEN 41-y AND 6 ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 {}}
do_test between-1.4 {
  queryplan {
    SELECT * FROM t1 WHERE w BETWEEN 41-y AND 65-y ORDER BY +w
  }
} {5 2 36 38 6 2 49 51 sort t1 {}}
do_test between-1.5.1 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN y AND z ORDER BY +w
  }
} {4 2 25 27 sort t1 i1zyx}
do_test between-1.5.2 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN +y AND z ORDER BY +w
  }
} {4 2 25 27 sort t1 i1zyx}
do_test between-1.5.3 {
  queryplan {
    SELECT * FROM t1 WHERE 26 BETWEEN y AND +z ORDER BY +w
  }
} {4 2 25 27 sort t1 {}}


finish_test
Changes to test/blob.test.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    CREATE INDEX i1 ON t1(a);
  }
  set blobs [execsql {SELECT * FROM t1}]
  set blobs2 [list]
  foreach b $blobs {lappend blobs2 [bin_to_hex $b]}
  set blobs2
} {123456 7890AB CDEF12 345678}

do_test blob-2.2 {
  set blobs [execsql {SELECT * FROM t1 where a = X'123456'}]
  set blobs2 [list]
  foreach b $blobs {lappend blobs2 [bin_to_hex $b]}
  set blobs2
} {123456 7890AB}
do_test blob-2.3 {







<







102
103
104
105
106
107
108

109
110
111
112
113
114
115
    CREATE INDEX i1 ON t1(a);
  }
  set blobs [execsql {SELECT * FROM t1}]
  set blobs2 [list]
  foreach b $blobs {lappend blobs2 [bin_to_hex $b]}
  set blobs2
} {123456 7890AB CDEF12 345678}

do_test blob-2.2 {
  set blobs [execsql {SELECT * FROM t1 where a = X'123456'}]
  set blobs2 [list]
  foreach b $blobs {lappend blobs2 [bin_to_hex $b]}
  set blobs2
} {123456 7890AB}
do_test blob-2.3 {
Changes to test/boundary3.tcl.
9
10
11
12
13
14
15

16
17
18
19
20
21
22
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file is automatically generated from a separate TCL script.
# This file seeks to exercise integer boundary values.
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Many of the boundary tests depend on a working 64-bit implementation.
if {![working_64bit_int]} { finish_test; return }
}







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file is automatically generated from a separate TCL script.
# This file seeks to exercise integer boundary values.
#
# $Id: boundary3.tcl,v 1.3 2009/01/02 15:45:48 shane Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Many of the boundary tests depend on a working 64-bit implementation.
if {![working_64bit_int]} { finish_test; return }
}
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  0x7fffffffff
  0x7fffffffffff
  0x7fffffffffffff
  0x7fffffffffffffff
} {
  set x [expr {wide($x)}]
  set boundarynum($x) 1
  set boundarynum([expr {wide($x+1)}]) 1
  set boundarynum([expr {wide(-($x+1))}]) 1
  set boundarynum([expr {wide(-($x+2))}]) 1
  set boundarynum([expr {wide($x+$x+1)}]) 1
  set boundarynum([expr {wide($x+$x+2)}]) 1
}
set x [expr {wide(127)}]
for {set i 1} {$i<=9} {incr i} {
  set boundarynum($x) 1
  set boundarynum([expr {wide($x+1)}]) 1
  set x [expr {wide($x*128 + 127)}]
}

# Scramble the $inlist into a random order.
#
proc scramble {inlist} {
  set y {}







|
|
|
|
|




|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  0x7fffffffff
  0x7fffffffffff
  0x7fffffffffffff
  0x7fffffffffffffff
} {
  set x [expr {wide($x)}]
  set boundarynum($x) 1
  set boundarynum([expr {$x+1}]) 1
  set boundarynum([expr {-($x+1)}]) 1
  set boundarynum([expr {-($x+2)}]) 1
  set boundarynum([expr {$x+$x+1}]) 1
  set boundarynum([expr {$x+$x+2}]) 1
}
set x [expr {wide(127)}]
for {set i 1} {$i<=9} {incr i} {
  set boundarynum($x) 1
  set boundarynum([expr {$x+1}]) 1
  set x [expr {wide($x*128 + 127)}]
}

# Scramble the $inlist into a random order.
#
proc scramble {inlist} {
  set y {}
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

set nums1 [scramble [array names boundarynum]]
set nums2 [scramble [array names boundarynum]]

set tname boundary3
puts "do_test $tname-1.1 \173"
puts "  db eval \173"
puts "    CREATE TABLE t1(oid PRIMARY KEY, a,x);"
set a 0
foreach r $nums1 {
  incr a
  set t1ra($r) $a
  set t1ar($a) $r
  set x [format %016x [expr {wide($r)}]]
  set t1rx($r) $x
  set t1xr($x) $r
  puts "    INSERT INTO t1(oid,a,x) VALUES($r,$a,'$x');"
}
puts "    CREATE INDEX t1i1 ON t1(a);"
puts "    CREATE INDEX t1i2 ON t1(x);"
puts "  \175"
puts "\175 {}"

puts "do_test $tname-1.2 \173"
puts "  db eval \173"
puts "    SELECT count(*) FROM t1"
puts "  \175"
puts "\175 {64}"

puts "do_test $tname-1.3 \173"
puts "  db eval \173"
puts "    CREATE TABLE t2(r,a);"
puts "    INSERT INTO t2 SELECT oid, a FROM t1;"
puts "    CREATE INDEX t2i1 ON t2(r);"
puts "    CREATE INDEX t2i2 ON t2(a);"
puts "    INSERT INTO t2 VALUES(9.22337303685477580800e+18,65);"
set t1ra(9.22337303685477580800e+18) 65
set t1ar(65) 9.22337303685477580800e+18)
puts "    INSERT INTO t2 VALUES(-9.22337303685477580800e+18,66);"
set t1ra(-9.22337303685477580800e+18) 66







|





|


















|







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

set nums1 [scramble [array names boundarynum]]
set nums2 [scramble [array names boundarynum]]

set tname boundary3
puts "do_test $tname-1.1 \173"
puts "  db eval \173"
puts "    CREATE TABLE t1(a,x);"
set a 0
foreach r $nums1 {
  incr a
  set t1ra($r) $a
  set t1ar($a) $r
  set x [format %08x%08x [expr {wide($r)>>32}] $r]
  set t1rx($r) $x
  set t1xr($x) $r
  puts "    INSERT INTO t1(oid,a,x) VALUES($r,$a,'$x');"
}
puts "    CREATE INDEX t1i1 ON t1(a);"
puts "    CREATE INDEX t1i2 ON t1(x);"
puts "  \175"
puts "\175 {}"

puts "do_test $tname-1.2 \173"
puts "  db eval \173"
puts "    SELECT count(*) FROM t1"
puts "  \175"
puts "\175 {64}"

puts "do_test $tname-1.3 \173"
puts "  db eval \173"
puts "    CREATE TABLE t2(r,a);"
puts "    INSERT INTO t2 SELECT rowid, a FROM t1;"
puts "    CREATE INDEX t2i1 ON t2(r);"
puts "    CREATE INDEX t2i2 ON t2(a);"
puts "    INSERT INTO t2 VALUES(9.22337303685477580800e+18,65);"
set t1ra(9.22337303685477580800e+18) 65
set t1ar(65) 9.22337303685477580800e+18)
puts "    INSERT INTO t2 VALUES(-9.22337303685477580800e+18,66);"
set t1ra(-9.22337303685477580800e+18) 66
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

set i 0
foreach r $nums3 {
  incr i

  set r5 $r.5
  set r0 $r.0
   if {abs($r)<0x7FFFFFFFFFFFFFFF || $r==-9223372036854775808} {
    set x $t1rx($r)
    set a $t1ra($r)
    puts "do_test $tname-2.$i.1 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=$r AND t2.a=t1.a"
    puts "  \175"
    puts "\175 {$a $x}"
    puts "do_test $tname-2.$i.2 \173"
    puts "  db eval \173"
    puts "    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='$x'"
    puts "  \175"
    puts "\175 {$r $a}"
    puts "do_test $tname-2.$i.3 \173"
    puts "  db eval \173"
    puts "    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=$a"
    puts "  \175"
    puts "\175 {$r $x}"
  }

  foreach op {> >= < <=} subno {gt ge lt le} {

    ################################################################ 2.x.y.1
    set rset {}
    set aset {}
    foreach rx $nums2 {
      if "\$rx $op \$r" {
        lappend rset $rx
        lappend aset $t1ra($rx)
      }
    }
    puts "do_test $tname-2.$i.$subno.1 \173"
    puts "  db eval \173"
    puts "    SELECT t2.a FROM t1 JOIN t2 USING(a)"
    puts "     WHERE t1.oid $op $r ORDER BY t2.a"
    puts "  \175"
    puts "\175 {[sort $aset]}"
  
    ################################################################ 2.x.y.2
    puts "do_test $tname-2.$i.$subno.2 \173"
    puts "  db eval \173"
    puts "    SELECT t2.a FROM t2 NATURAL JOIN t1"
    puts "     WHERE t1.oid $op $r ORDER BY t1.a DESC"
    puts "  \175"
    puts "\175 {[reverse [sort $aset]]}"


    ################################################################ 2.x.y.3
    set ax $t1ra($r)
    set aset {}
    foreach rx [sort $rset] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.3 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.oid $op t2.r"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.oid"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.4
    set aset {}
    foreach rx [reverse [sort $rset]] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.4 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.oid $op t2.r"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.oid DESC"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.5
    set aset {}
    set xset {}
    foreach rx $rset {
      lappend xset $t1rx($rx)
    }
    foreach x [sort $xset] {
      set rx $t1xr($x)
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.5 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.oid $op t2.r"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY x"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.10
    if {[string length $r5]>15} continue
    set rset {}
    set aset {}
    foreach rx $nums2 {
      if "\$rx $op \$r0" {
        lappend rset $rx
      }
    }
    foreach rx [sort $rset] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.10 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.oid $op CAST(t2.r AS real)"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.oid"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.11
    set aset {}
    foreach rx [reverse [sort $rset]] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.11 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.oid $op CAST(t2.r AS real)"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.oid DESC"
    puts "  \175"
    puts "\175 {$aset}"
  }
  
}


puts {finish_test}







|




|









|


















|







|












|

|










|

|















|



















|

|










|

|








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

set i 0
foreach r $nums3 {
  incr i

  set r5 $r.5
  set r0 $r.0
  if {abs($r)<9.22337203685477580800e+18} {
    set x $t1rx($r)
    set a $t1ra($r)
    puts "do_test $tname-2.$i.1 \173"
    puts "  db eval \173"
    puts "    SELECT t1.* FROM t1, t2 WHERE t1.rowid=$r AND t2.a=t1.a"
    puts "  \175"
    puts "\175 {$a $x}"
    puts "do_test $tname-2.$i.2 \173"
    puts "  db eval \173"
    puts "    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='$x'"
    puts "  \175"
    puts "\175 {$r $a}"
    puts "do_test $tname-2.$i.3 \173"
    puts "  db eval \173"
    puts "    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=$a"
    puts "  \175"
    puts "\175 {$r $x}"
  }

  foreach op {> >= < <=} subno {gt ge lt le} {

    ################################################################ 2.x.y.1
    set rset {}
    set aset {}
    foreach rx $nums2 {
      if "\$rx $op \$r" {
        lappend rset $rx
        lappend aset $t1ra($rx)
      }
    }
    puts "do_test $tname-2.$i.$subno.1 \173"
    puts "  db eval \173"
    puts "    SELECT t2.a FROM t1 JOIN t2 USING(a)"
    puts "     WHERE t1.rowid $op $r ORDER BY t2.a"
    puts "  \175"
    puts "\175 {[sort $aset]}"
  
    ################################################################ 2.x.y.2
    puts "do_test $tname-2.$i.$subno.2 \173"
    puts "  db eval \173"
    puts "    SELECT t2.a FROM t2 NATURAL JOIN t1"
    puts "     WHERE t1.rowid $op $r ORDER BY t1.a DESC"
    puts "  \175"
    puts "\175 {[reverse [sort $aset]]}"


    ################################################################ 2.x.y.3
    set ax $t1ra($r)
    set aset {}
    foreach rx [sort $rset] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.3 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid $op t2.r"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.rowid"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.4
    set aset {}
    foreach rx [reverse [sort $rset]] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.4 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid $op t2.r"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.rowid DESC"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.5
    set aset {}
    set xset {}
    foreach rx $rset {
      lappend xset $t1rx($rx)
    }
    foreach x [sort $xset] {
      set rx $t1xr($x)
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.5 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid $op t2.r"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY x"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.10
    if {[string length $r5]>15} continue
    set rset {}
    set aset {}
    foreach rx $nums2 {
      if "\$rx $op \$r0" {
        lappend rset $rx
      }
    }
    foreach rx [sort $rset] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.10 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid $op CAST(t2.r AS real)"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.rowid"
    puts "  \175"
    puts "\175 {$aset}"
  
    ################################################################ 2.x.y.11
    set aset {}
    foreach rx [reverse [sort $rset]] {
      lappend aset $t1ra($rx)
    }
    puts "do_test $tname-2.$i.$subno.11 \173"
    puts "  db eval \173"
    puts "    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid $op CAST(t2.r AS real)"
    puts "     WHERE t2.a=$ax"
    puts "     ORDER BY t1.rowid DESC"
    puts "  \175"
    puts "\175 {$aset}"
  }
  
}


puts {finish_test}
Changes to test/boundary3.test.
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file is automatically generated from a separate TCL script.
# This file seeks to exercise integer boundary values.
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Many of the boundary tests depend on a working 64-bit implementation.
if {![working_64bit_int]} { finish_test; return }

do_test boundary3-1.1 {
  db eval {
    CREATE TABLE t1(oid PRIMARY KEY, a,x);
    INSERT INTO t1(oid,a,x) VALUES(-8388609,1,'ffffffffff7fffff');
    INSERT INTO t1(oid,a,x) VALUES(-36028797018963969,2,'ff7fffffffffffff');
    INSERT INTO t1(oid,a,x) VALUES(9223372036854775807,3,'7fffffffffffffff');
    INSERT INTO t1(oid,a,x) VALUES(127,4,'000000000000007f');
    INSERT INTO t1(oid,a,x) VALUES(3,5,'0000000000000003');
    INSERT INTO t1(oid,a,x) VALUES(16777216,6,'0000000001000000');
    INSERT INTO t1(oid,a,x) VALUES(4398046511103,7,'000003ffffffffff');







>









|







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
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file is automatically generated from a separate TCL script.
# This file seeks to exercise integer boundary values.
#
# $Id: boundary3.test,v 1.2 2009/01/02 15:45:48 shane Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Many of the boundary tests depend on a working 64-bit implementation.
if {![working_64bit_int]} { finish_test; return }

do_test boundary3-1.1 {
  db eval {
    CREATE TABLE t1(a,x);
    INSERT INTO t1(oid,a,x) VALUES(-8388609,1,'ffffffffff7fffff');
    INSERT INTO t1(oid,a,x) VALUES(-36028797018963969,2,'ff7fffffffffffff');
    INSERT INTO t1(oid,a,x) VALUES(9223372036854775807,3,'7fffffffffffffff');
    INSERT INTO t1(oid,a,x) VALUES(127,4,'000000000000007f');
    INSERT INTO t1(oid,a,x) VALUES(3,5,'0000000000000003');
    INSERT INTO t1(oid,a,x) VALUES(16777216,6,'0000000001000000');
    INSERT INTO t1(oid,a,x) VALUES(4398046511103,7,'000003ffffffffff');
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
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
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
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
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
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
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
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
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
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
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
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
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
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
2321
2322
2323
2324
2325
2326
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
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
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
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
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
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
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
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
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
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
2706
2707
2708
2709
2710
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
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
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
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
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
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
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
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
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
3188
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
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
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
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
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
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
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
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
3660
3661
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
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
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
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
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
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
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
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
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
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
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
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
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
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
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
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
  db eval {
    SELECT count(*) FROM t1
  }
} {64}
do_test boundary3-1.3 {
  db eval {
    CREATE TABLE t2(r,a);
    INSERT INTO t2 SELECT oid, a FROM t1;
    CREATE INDEX t2i1 ON t2(r);
    CREATE INDEX t2i2 ON t2(a);
    INSERT INTO t2 VALUES(9.22337303685477580800e+18,65);
    INSERT INTO t2 VALUES(-9.22337303685477580800e+18,66);
    SELECT count(*) FROM t2;
  }
} {66}
do_test boundary3-2.1.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=72057594037927935 AND t2.a=t1.a
  }
} {17 00ffffffffffffff}
do_test boundary3-2.1.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00ffffffffffffff'
  }
} {72057594037927935 17}
do_test boundary3-2.1.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=17
  }
} {72057594037927935 00ffffffffffffff}
do_test boundary3-2.1.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 72057594037927935 ORDER BY t2.a
  }
} {3 28}
do_test boundary3-2.1.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 72057594037927935 ORDER BY t1.a DESC
  }
} {28 3}
do_test boundary3-2.1.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=17
     ORDER BY t1.oid
  }
} {28 3}
do_test boundary3-2.1.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=17
     ORDER BY t1.oid DESC
  }
} {3 28}
do_test boundary3-2.1.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {28 3}
do_test boundary3-2.1.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 72057594037927935 ORDER BY t2.a
  }
} {3 17 28}
do_test boundary3-2.1.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 72057594037927935 ORDER BY t1.a DESC
  }
} {28 17 3}
do_test boundary3-2.1.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=17
     ORDER BY t1.oid
  }
} {17 28 3}
do_test boundary3-2.1.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=17
     ORDER BY t1.oid DESC
  }
} {3 28 17}
do_test boundary3-2.1.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {17 28 3}
do_test boundary3-2.1.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 72057594037927935 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.1.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 72057594037927935 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.1.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=17
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45}
do_test boundary3-2.1.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=17
     ORDER BY t1.oid DESC
  }
} {45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.1.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.1.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 72057594037927935 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.1.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 72057594037927935 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.1.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=17
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17}
do_test boundary3-2.1.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=17
     ORDER BY t1.oid DESC
  }
} {17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.1.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.2.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=16384 AND t2.a=t1.a
  }
} {16 0000000000004000}
do_test boundary3-2.2.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000004000'
  }
} {16384 16}
do_test boundary3-2.2.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=16
  }
} {16384 0000000000004000}
do_test boundary3-2.2.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 16384 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.2.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 16384 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.2.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.2.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.2.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 16384 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.2.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 16384 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.2.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.2.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.2.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 16384 ORDER BY t2.a
  }
} {1 2 4 5 8 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.2.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 16384 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 8 5 4 2 1}
do_test boundary3-2.2.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.2.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.2.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.2.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.2.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.2.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 16384 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.2.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 16384 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 16 11 8 5 4 2 1}
do_test boundary3-2.2.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.2.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.2.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.2.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.2.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.oid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=4294967296 AND t2.a=t1.a
  }
} {36 0000000100000000}
do_test boundary3-2.3.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000100000000'
  }
} {4294967296 36}
do_test boundary3-2.3.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=36
  }
} {4294967296 0000000100000000}
do_test boundary3-2.3.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 4294967296 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 39 43 45 46 56 57}
do_test boundary3-2.3.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 4294967296 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.3.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.3.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.3.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 4294967296 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.3.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 4294967296 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.3.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.3.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.3.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 4294967296 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.3.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 4294967296 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.3.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.3.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.3.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.3.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 4294967296 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.3.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 4294967296 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.3.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.3.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.3.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.3.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.oid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=16777216 AND t2.a=t1.a
  }
} {6 0000000001000000}
do_test boundary3-2.4.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000001000000'
  }
} {16777216 6}
do_test boundary3-2.4.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=6
  }
} {16777216 0000000001000000}
do_test boundary3-2.4.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 16777216 ORDER BY t2.a
  }
} {3 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.4.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 16777216 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 3}
do_test boundary3-2.4.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.4.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.4.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 16777216 ORDER BY t2.a
  }
} {3 6 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.4.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 16777216 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 6 3}
do_test boundary3-2.4.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.4.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.4.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 16777216 ORDER BY t2.a
  }
} {1 2 4 5 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.4.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 16777216 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 5 4 2 1}
do_test boundary3-2.4.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.4.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.4.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.4.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 16777216 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.4.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 16777216 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 6 5 4 2 1}
do_test boundary3-2.4.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.4.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.4.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.4.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.oid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-32769 AND t2.a=t1.a
  }
} {29 ffffffffffff7fff}
do_test boundary3-2.5.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffff7fff'
  }
} {-32769 29}
do_test boundary3-2.5.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=29
  }
} {-32769 ffffffffffff7fff}
do_test boundary3-2.5.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -32769 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.5.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -32769 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.5.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.5.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 32 54 53 52 33 38}
do_test boundary3-2.5.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.5.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -32769 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.5.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -32769 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.5.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.5.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 29 32 54 53 52 33 38}
do_test boundary3-2.5.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.5.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -32769 ORDER BY t2.a
  }
} {1 2 11 21 37 44 47 55 58 63 64}
do_test boundary3-2.5.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -32769 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 21 11 2 1}
do_test boundary3-2.5.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.5.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.5.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.5.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -32769 ORDER BY t2.a
  }
} {1 2 11 21 29 37 44 47 55 58 63 64}
do_test boundary3-2.5.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -32769 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 29 21 11 2 1}
do_test boundary3-2.5.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.5.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.5.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.5.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.oid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.6.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-140737488355329 AND t2.a=t1.a
  }
} {21 ffff7fffffffffff}
do_test boundary3-2.6.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffff7fffffffffff'
  }
} {-140737488355329 21}
do_test boundary3-2.6.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=21
  }
} {-140737488355329 ffff7fffffffffff}
do_test boundary3-2.6.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -140737488355329 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.6.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -140737488355329 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.6.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=21
     ORDER BY t1.oid
  }
} {44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.6.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=21
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44}
do_test boundary3-2.6.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.6.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -140737488355329 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.6.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -140737488355329 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.6.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=21
     ORDER BY t1.oid
  }
} {21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.6.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=21
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21}
do_test boundary3-2.6.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.6.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -140737488355329 ORDER BY t2.a
  }
} {2 55 64}
do_test boundary3-2.6.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -140737488355329 ORDER BY t1.a DESC
  }
} {64 55 2}
do_test boundary3-2.6.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=21
     ORDER BY t1.oid
  }
} {55 2 64}
do_test boundary3-2.6.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=21
     ORDER BY t1.oid DESC
  }
} {64 2 55}
do_test boundary3-2.6.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {55 2 64}
do_test boundary3-2.6.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -140737488355329 ORDER BY t2.a
  }
} {2 21 55 64}
do_test boundary3-2.6.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -140737488355329 ORDER BY t1.a DESC
  }
} {64 55 21 2}
do_test boundary3-2.6.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=21
     ORDER BY t1.oid
  }
} {55 2 64 21}
do_test boundary3-2.6.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=21
     ORDER BY t1.oid DESC
  }
} {21 64 2 55}
do_test boundary3-2.6.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {55 2 64 21}
do_test boundary3-2.7.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=2 AND t2.a=t1.a
  }
} {41 0000000000000002}
do_test boundary3-2.7.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000002'
  }
} {2 41}
do_test boundary3-2.7.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=41
  }
} {2 0000000000000002}
do_test boundary3-2.7.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.7.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 2 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.7.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.7.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.7.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.7.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 2 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.7.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.7.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.7.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.7.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 2 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.7.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.7.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.7.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {59 60 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.7.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.7.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.7.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.7.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 2 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.7.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.7.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.7.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {59 60 41 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.7.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.7.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.oid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=4 AND t2.a=t1.a
  }
} {31 0000000000000004}
do_test boundary3-2.8.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000004'
  }
} {4 31}
do_test boundary3-2.8.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=31
  }
} {4 0000000000000004}
do_test boundary3-2.8.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 4 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.8.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 4 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.8.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.8.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.8.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 4 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.8.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 4 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.8.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.8.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.8.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 4 ORDER BY t2.a
  }
} {1 2 5 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.8.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 4 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 5 2 1}
do_test boundary3-2.8.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.8.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {59 60 41 5 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.8.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.8.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 4 ORDER BY t2.a
  }
} {1 2 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.8.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 4 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 2 1}
do_test boundary3-2.8.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.8.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {59 60 41 5 31 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.8.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.8.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.oid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.9.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=562949953421311 AND t2.a=t1.a
  }
} {13 0001ffffffffffff}
do_test boundary3-2.9.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0001ffffffffffff'
  }
} {562949953421311 13}
do_test boundary3-2.9.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=13
  }
} {562949953421311 0001ffffffffffff}
do_test boundary3-2.9.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 562949953421311 ORDER BY t2.a
  }
} {3 17 27 28 43 45}
do_test boundary3-2.9.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 562949953421311 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 3}
do_test boundary3-2.9.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=13
     ORDER BY t1.oid
  }
} {43 27 45 17 28 3}
do_test boundary3-2.9.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=13
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43}
do_test boundary3-2.9.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {43 27 45 17 28 3}
do_test boundary3-2.9.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 562949953421311 ORDER BY t2.a
  }
} {3 13 17 27 28 43 45}
do_test boundary3-2.9.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 562949953421311 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 13 3}
do_test boundary3-2.9.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=13
     ORDER BY t1.oid
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.9.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=13
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13}
do_test boundary3-2.9.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.9.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 562949953421311 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.9.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 562949953421311 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.9.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=13
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26}
do_test boundary3-2.9.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=13
     ORDER BY t1.oid DESC
  }
} {26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.9.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.9.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 562949953421311 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.9.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 562949953421311 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.9.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=13
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13}
do_test boundary3-2.9.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=13
     ORDER BY t1.oid DESC
  }
} {13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.9.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.10.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=256 AND t2.a=t1.a
  }
} {61 0000000000000100}
do_test boundary3-2.10.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000100'
  }
} {256 61}
do_test boundary3-2.10.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=61
  }
} {256 0000000000000100}
do_test boundary3-2.10.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 256 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.10.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 256 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.10.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.10.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.10.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 256 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.10.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 256 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.10.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.10.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.10.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 256 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.10.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 256 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.10.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.10.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.10.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.10.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.10.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.10.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 256 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.10.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 256 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.10.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.10.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.10.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.10.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.10.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.oid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=34359738368 AND t2.a=t1.a
  }
} {22 0000000800000000}
do_test boundary3-2.11.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000800000000'
  }
} {34359738368 22}
do_test boundary3-2.11.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=22
  }
} {34359738368 0000000800000000}
do_test boundary3-2.11.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 34359738368 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.11.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 34359738368 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.11.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.11.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.11.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 34359738368 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.11.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 34359738368 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.11.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.11.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.11.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 34359738368 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.11.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 34359738368 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.11.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.11.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.11.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.11.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 34359738368 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.11.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 34359738368 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.11.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.11.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.11.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.11.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.oid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=65536 AND t2.a=t1.a
  }
} {62 0000000000010000}
do_test boundary3-2.12.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000010000'
  }
} {65536 62}
do_test boundary3-2.12.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=62
  }
} {65536 0000000000010000}
do_test boundary3-2.12.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 65536 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.12.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 65536 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.12.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.12.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.12.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 65536 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57 62}
do_test boundary3-2.12.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 65536 ORDER BY t1.a DESC
  }
} {62 57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.12.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.12.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.12.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 65536 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.12.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 65536 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.12.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.12.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.12.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.12.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 65536 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.12.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 65536 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.12.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.12.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.12.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.12.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.oid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=268435456 AND t2.a=t1.a
  }
} {40 0000000010000000}
do_test boundary3-2.13.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000010000000'
  }
} {268435456 40}
do_test boundary3-2.13.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=40
  }
} {268435456 0000000010000000}
do_test boundary3-2.13.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 268435456 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.13.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 268435456 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.13.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.13.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.13.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 268435456 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.13.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 268435456 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.13.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.13.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.13.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 268435456 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.13.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 268435456 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.13.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.13.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.13.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.13.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 268435456 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.13.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 268435456 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.13.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.13.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.13.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.13.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.oid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.14.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-140737488355328 AND t2.a=t1.a
  }
} {44 ffff800000000000}
do_test boundary3-2.14.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffff800000000000'
  }
} {-140737488355328 44}
do_test boundary3-2.14.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=44
  }
} {-140737488355328 ffff800000000000}
do_test boundary3-2.14.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -140737488355328 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 58 59 60 61 62 63}
do_test boundary3-2.14.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -140737488355328 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.14.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=44
     ORDER BY t1.oid
  }
} {58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.14.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=44
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58}
do_test boundary3-2.14.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.14.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -140737488355328 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.14.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -140737488355328 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.14.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=44
     ORDER BY t1.oid
  }
} {44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.14.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=44
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44}
do_test boundary3-2.14.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.14.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -140737488355328 ORDER BY t2.a
  }
} {2 21 55 64}
do_test boundary3-2.14.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -140737488355328 ORDER BY t1.a DESC
  }
} {64 55 21 2}
do_test boundary3-2.14.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=44
     ORDER BY t1.oid
  }
} {55 2 64 21}
do_test boundary3-2.14.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=44
     ORDER BY t1.oid DESC
  }
} {21 64 2 55}
do_test boundary3-2.14.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {55 2 64 21}
do_test boundary3-2.14.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -140737488355328 ORDER BY t2.a
  }
} {2 21 44 55 64}
do_test boundary3-2.14.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -140737488355328 ORDER BY t1.a DESC
  }
} {64 55 44 21 2}
do_test boundary3-2.14.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=44
     ORDER BY t1.oid
  }
} {55 2 64 21 44}
do_test boundary3-2.14.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=44
     ORDER BY t1.oid DESC
  }
} {44 21 64 2 55}
do_test boundary3-2.14.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {55 2 64 21 44}
do_test boundary3-2.15.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=1099511627776 AND t2.a=t1.a
  }
} {19 0000010000000000}
do_test boundary3-2.15.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000010000000000'
  }
} {1099511627776 19}
do_test boundary3-2.15.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=19
  }
} {1099511627776 0000010000000000}
do_test boundary3-2.15.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 1099511627776 ORDER BY t2.a
  }
} {3 7 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.15.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 1099511627776 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 7 3}
do_test boundary3-2.15.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.15.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.15.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 1099511627776 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56}
do_test boundary3-2.15.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 1099511627776 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.15.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.15.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.15.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 1099511627776 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.15.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 1099511627776 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.15.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.15.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.15.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.15.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.15.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.15.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 1099511627776 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.15.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 1099511627776 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.15.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.15.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.15.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.15.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.15.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.oid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.16.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 9223372036854775807 ORDER BY t2.a
  }
} {}
do_test boundary3-2.16.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 9223372036854775807 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.16.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=3
     ORDER BY t1.oid
  }
} {}
do_test boundary3-2.16.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=3
     ORDER BY t1.oid DESC
  }
} {}
do_test boundary3-2.16.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {}
do_test boundary3-2.16.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 9223372036854775807 ORDER BY t2.a
  }
} {3}
do_test boundary3-2.16.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 9223372036854775807 ORDER BY t1.a DESC
  }
} {3}
do_test boundary3-2.16.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=3
     ORDER BY t1.oid
  }
} {3}
do_test boundary3-2.16.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=3
     ORDER BY t1.oid DESC
  }
} {3}
do_test boundary3-2.16.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {3}
do_test boundary3-2.16.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 9223372036854775807 ORDER BY t2.a
  }
} {1 2 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}
do_test boundary3-2.16.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 9223372036854775807 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.16.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=3
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28}
do_test boundary3-2.16.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=3
     ORDER BY t1.oid DESC
  }
} {28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.16.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.16.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 9223372036854775807 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.16.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 9223372036854775807 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.16.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=3
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.16.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=3
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.16.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.17.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=32768 AND t2.a=t1.a
  }
} {50 0000000000008000}
do_test boundary3-2.17.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000008000'
  }
} {32768 50}
do_test boundary3-2.17.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=50
  }
} {32768 0000000000008000}
do_test boundary3-2.17.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 32768 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 51 56 57 62}
do_test boundary3-2.17.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 32768 ORDER BY t1.a DESC
  }
} {62 57 56 51 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.17.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.17.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.17.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 32768 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.17.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 32768 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.17.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.17.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.17.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 32768 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.17.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 32768 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.17.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.17.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.17.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.17.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.17.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.17.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 32768 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.17.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 32768 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.17.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.17.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.17.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.17.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.17.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.oid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.18.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-36028797018963968 AND t2.a=t1.a
  }
} {64 ff80000000000000}
do_test boundary3-2.18.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ff80000000000000'
  }
} {-36028797018963968 64}
do_test boundary3-2.18.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=64
  }
} {-36028797018963968 ff80000000000000}
do_test boundary3-2.18.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -36028797018963968 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.18.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -36028797018963968 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.18.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=64
     ORDER BY t1.oid
  }
} {21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.18.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=64
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21}
do_test boundary3-2.18.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.18.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -36028797018963968 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.18.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -36028797018963968 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.18.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=64
     ORDER BY t1.oid
  }
} {64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.18.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=64
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64}
do_test boundary3-2.18.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.18.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -36028797018963968 ORDER BY t2.a
  }
} {2 55}
do_test boundary3-2.18.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -36028797018963968 ORDER BY t1.a DESC
  }
} {55 2}
do_test boundary3-2.18.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=64
     ORDER BY t1.oid
  }
} {55 2}
do_test boundary3-2.18.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=64
     ORDER BY t1.oid DESC
  }
} {2 55}
do_test boundary3-2.18.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {55 2}
do_test boundary3-2.18.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -36028797018963968 ORDER BY t2.a
  }
} {2 55 64}
do_test boundary3-2.18.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -36028797018963968 ORDER BY t1.a DESC
  }
} {64 55 2}
do_test boundary3-2.18.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=64
     ORDER BY t1.oid
  }
} {55 2 64}
do_test boundary3-2.18.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=64
     ORDER BY t1.oid DESC
  }
} {64 2 55}
do_test boundary3-2.18.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {55 2 64}
do_test boundary3-2.19.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=65535 AND t2.a=t1.a
  }
} {48 000000000000ffff}
do_test boundary3-2.19.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000000000ffff'
  }
} {65535 48}
do_test boundary3-2.19.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=48
  }
} {65535 000000000000ffff}
do_test boundary3-2.19.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 65535 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57 62}
do_test boundary3-2.19.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 65535 ORDER BY t1.a DESC
  }
} {62 57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.19.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.19.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.19.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 65535 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 51 56 57 62}
do_test boundary3-2.19.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 65535 ORDER BY t1.a DESC
  }
} {62 57 56 51 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.19.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.19.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.19.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 65535 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.19.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 65535 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.19.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.19.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.19.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.19.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.19.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.19.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 65535 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.19.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 65535 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.19.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.19.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.19.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.19.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.19.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.oid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=4294967295 AND t2.a=t1.a
  }
} {14 00000000ffffffff}
do_test boundary3-2.20.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000ffffffff'
  }
} {4294967295 14}
do_test boundary3-2.20.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=14
  }
} {4294967295 00000000ffffffff}
do_test boundary3-2.20.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 4294967295 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.20.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 4294967295 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.20.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.20.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.20.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 4294967295 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.20.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 4294967295 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.20.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.20.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.20.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 4294967295 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.20.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 4294967295 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.20.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.20.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.20.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.20.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 4294967295 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.20.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 4294967295 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.20.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.20.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.20.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.20.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.oid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=1099511627775 AND t2.a=t1.a
  }
} {57 000000ffffffffff}
do_test boundary3-2.21.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000ffffffffff'
  }
} {1099511627775 57}
do_test boundary3-2.21.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=57
  }
} {1099511627775 000000ffffffffff}
do_test boundary3-2.21.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 1099511627775 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56}
do_test boundary3-2.21.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 1099511627775 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.21.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.21.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.21.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 1099511627775 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56 57}
do_test boundary3-2.21.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 1099511627775 ORDER BY t1.a DESC
  }
} {57 56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.21.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.21.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.21.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 1099511627775 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.21.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 1099511627775 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.21.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.21.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.21.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.21.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 1099511627775 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.21.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 1099511627775 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.21.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.21.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.21.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.21.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.oid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-8388608 AND t2.a=t1.a
  }
} {37 ffffffffff800000}
do_test boundary3-2.22.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffff800000'
  }
} {-8388608 37}
do_test boundary3-2.22.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=37
  }
} {-8388608 ffffffffff800000}
do_test boundary3-2.22.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -8388608 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.22.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -8388608 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.22.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.22.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 29 32 54 53 52 33 38}
do_test boundary3-2.22.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.22.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -8388608 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.22.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -8388608 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.22.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.22.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 37 29 32 54 53 52 33 38}
do_test boundary3-2.22.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.22.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -8388608 ORDER BY t2.a
  }
} {1 2 11 21 44 47 55 58 63 64}
do_test boundary3-2.22.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -8388608 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2 1}
do_test boundary3-2.22.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.22.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.22.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.22.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -8388608 ORDER BY t2.a
  }
} {1 2 11 21 37 44 47 55 58 63 64}
do_test boundary3-2.22.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -8388608 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 21 11 2 1}
do_test boundary3-2.22.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.22.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.22.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.22.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.oid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=549755813888 AND t2.a=t1.a
  }
} {35 0000008000000000}
do_test boundary3-2.23.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000008000000000'
  }
} {549755813888 35}
do_test boundary3-2.23.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=35
  }
} {549755813888 0000008000000000}
do_test boundary3-2.23.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 549755813888 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56 57}
do_test boundary3-2.23.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 549755813888 ORDER BY t1.a DESC
  }
} {57 56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.23.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.23.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.23.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 549755813888 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 56 57}
do_test boundary3-2.23.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 549755813888 ORDER BY t1.a DESC
  }
} {57 56 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.23.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.23.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.23.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 549755813888 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.23.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 549755813888 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.23.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.23.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.23.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.23.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 549755813888 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.23.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 549755813888 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.23.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.23.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.23.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.23.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.oid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=8388607 AND t2.a=t1.a
  }
} {18 00000000007fffff}
do_test boundary3-2.24.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000007fffff'
  }
} {8388607 18}
do_test boundary3-2.24.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=18
  }
} {8388607 00000000007fffff}
do_test boundary3-2.24.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 8388607 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.24.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 8388607 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.24.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.24.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.24.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 8388607 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.24.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 8388607 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.24.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.24.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.24.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 8388607 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.24.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 8388607 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.24.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.24.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.24.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.24.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 8388607 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.24.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 8388607 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.24.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.24.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.24.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.24.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.oid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-3 AND t2.a=t1.a
  }
} {52 fffffffffffffffd}
do_test boundary3-2.25.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='fffffffffffffffd'
  }
} {-3 52}
do_test boundary3-2.25.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=52
  }
} {-3 fffffffffffffffd}
do_test boundary3-2.25.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -3 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.25.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -3 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.25.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.25.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 33 38}
do_test boundary3-2.25.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.25.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -3 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 56 57 59 60 61 62}
do_test boundary3-2.25.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -3 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.25.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.25.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 52 33 38}
do_test boundary3-2.25.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.25.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -3 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 53 54 55 58 63 64}
do_test boundary3-2.25.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -3 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.25.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.25.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.25.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.25.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -3 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.25.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -3 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.25.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.25.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.25.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.25.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.oid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=0 AND t2.a=t1.a
  }
} {59 0000000000000000}
do_test boundary3-2.26.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000000'
  }
} {0 59}
do_test boundary3-2.26.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=59
  }
} {0 0000000000000000}
do_test boundary3-2.26.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 0 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 60 61 62}
do_test boundary3-2.26.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 0 ORDER BY t1.a DESC
  }
} {62 61 60 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.26.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.26.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.26.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 0 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.26.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 0 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.26.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.26.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.26.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 0 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.26.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 0 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.26.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 0 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 63 64}
do_test boundary3-2.26.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 0 ORDER BY t1.a DESC
  }
} {64 63 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.26.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.26.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {59 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.26.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.oid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-1 AND t2.a=t1.a
  }
} {38 ffffffffffffffff}
do_test boundary3-2.27.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffffffff'
  }
} {-1 38}
do_test boundary3-2.27.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=38
  }
} {-1 ffffffffffffffff}
do_test boundary3-2.27.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.27.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -1 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.27.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.27.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.27.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.27.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -1 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.27.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.27.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 38}
do_test boundary3-2.27.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.27.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.27.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -1 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 33 32 29 21 11 2 1}
do_test boundary3-2.27.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.27.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.27.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.27.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.27.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -1 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.27.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.27.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.27.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.27.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.oid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-2 AND t2.a=t1.a
  }
} {33 fffffffffffffffe}
do_test boundary3-2.28.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='fffffffffffffffe'
  }
} {-2 33}
do_test boundary3-2.28.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=33
  }
} {-2 fffffffffffffffe}
do_test boundary3-2.28.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.28.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -2 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.28.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.28.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 38}
do_test boundary3-2.28.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.28.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.28.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -2 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.28.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.28.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 33 38}
do_test boundary3-2.28.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.28.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.28.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -2 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.28.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.28.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.28.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.28.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.28.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -2 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 33 32 29 21 11 2 1}
do_test boundary3-2.28.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.28.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.28.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.28.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.oid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=2097152 AND t2.a=t1.a
  }
} {42 0000000000200000}
do_test boundary3-2.29.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000200000'
  }
} {2097152 42}
do_test boundary3-2.29.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=42
  }
} {2097152 0000000000200000}
do_test boundary3-2.29.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 2097152 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.29.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 2097152 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.29.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.29.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.29.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 2097152 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.29.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 2097152 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.29.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.29.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.29.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 2097152 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.29.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 2097152 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.29.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.29.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.29.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.29.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 2097152 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.29.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 2097152 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.29.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.29.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.29.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.29.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.oid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=128 AND t2.a=t1.a
  }
} {49 0000000000000080}
do_test boundary3-2.30.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000080'
  }
} {128 49}
do_test boundary3-2.30.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=49
  }
} {128 0000000000000080}
do_test boundary3-2.30.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 128 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.30.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 128 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.30.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.30.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.30.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 128 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.30.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 128 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.30.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.30.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.30.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 128 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.30.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 128 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.30.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.30.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {59 60 41 5 31 4 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.30.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.30.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 128 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.30.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 128 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.30.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.30.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {59 60 41 5 31 4 49 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.30.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.30.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.oid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=255 AND t2.a=t1.a
  }
} {30 00000000000000ff}
do_test boundary3-2.31.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000000000ff'
  }
} {255 30}
do_test boundary3-2.31.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=30
  }
} {255 00000000000000ff}
do_test boundary3-2.31.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 255 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.31.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 255 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.31.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.31.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.31.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 255 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.31.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 255 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.31.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.31.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.31.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 255 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.31.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 255 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.31.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.31.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {59 60 41 5 31 4 49 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.31.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.31.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 255 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.31.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 255 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.31.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.31.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.31.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.31.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.oid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.32.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-2147483648 AND t2.a=t1.a
  }
} {11 ffffffff80000000}
do_test boundary3-2.32.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffff80000000'
  }
} {-2147483648 11}
do_test boundary3-2.32.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=11
  }
} {-2147483648 ffffffff80000000}
do_test boundary3-2.32.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -2147483648 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.32.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -2147483648 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.32.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.32.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.32.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.32.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -2147483648 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.32.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -2147483648 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.32.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.32.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.32.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.32.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -2147483648 ORDER BY t2.a
  }
} {2 21 44 47 55 58 63 64}
do_test boundary3-2.32.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -2147483648 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 2}
do_test boundary3-2.32.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.32.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.32.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.32.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.32.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.32.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -2147483648 ORDER BY t2.a
  }
} {2 11 21 44 47 55 58 63 64}
do_test boundary3-2.32.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -2147483648 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2}
do_test boundary3-2.32.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.32.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.32.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.32.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.32.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.oid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=34359738367 AND t2.a=t1.a
  }
} {39 00000007ffffffff}
do_test boundary3-2.33.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000007ffffffff'
  }
} {34359738367 39}
do_test boundary3-2.33.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=39
  }
} {34359738367 00000007ffffffff}
do_test boundary3-2.33.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 34359738367 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.33.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 34359738367 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.33.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.33.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.33.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 34359738367 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 39 43 45 46 56 57}
do_test boundary3-2.33.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 34359738367 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.33.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.33.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.33.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 34359738367 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.33.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 34359738367 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.33.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.33.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.33.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.33.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 34359738367 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.33.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 34359738367 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.33.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.33.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.33.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.33.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.oid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.34.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-549755813889 AND t2.a=t1.a
  }
} {58 ffffff7fffffffff}
do_test boundary3-2.34.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffff7fffffffff'
  }
} {-549755813889 58}
do_test boundary3-2.34.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=58
  }
} {-549755813889 ffffff7fffffffff}
do_test boundary3-2.34.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -549755813889 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62 63}
do_test boundary3-2.34.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -549755813889 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.34.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.34.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.34.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.34.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -549755813889 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 58 59 60 61 62 63}
do_test boundary3-2.34.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -549755813889 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.34.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58}
do_test boundary3-2.34.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.34.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58}
do_test boundary3-2.34.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -549755813889 ORDER BY t2.a
  }
} {2 21 44 55 64}
do_test boundary3-2.34.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -549755813889 ORDER BY t1.a DESC
  }
} {64 55 44 21 2}
do_test boundary3-2.34.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {55 2 64 21 44}
do_test boundary3-2.34.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {44 21 64 2 55}
do_test boundary3-2.34.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {55 2 64 21 44}
do_test boundary3-2.34.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {55 2 64 21 44}
do_test boundary3-2.34.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {44 21 64 2 55}
do_test boundary3-2.34.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -549755813889 ORDER BY t2.a
  }
} {2 21 44 55 58 64}
do_test boundary3-2.34.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -549755813889 ORDER BY t1.a DESC
  }
} {64 58 55 44 21 2}
do_test boundary3-2.34.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.34.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.34.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {55 2 64 21 44 58}
do_test boundary3-2.34.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.34.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.oid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.35.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-32768 AND t2.a=t1.a
  }
} {32 ffffffffffff8000}
do_test boundary3-2.35.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffff8000'
  }
} {-32768 32}
do_test boundary3-2.35.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=32
  }
} {-32768 ffffffffffff8000}
do_test boundary3-2.35.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -32768 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.35.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -32768 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.35.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.35.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 54 53 52 33 38}
do_test boundary3-2.35.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.35.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -32768 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.35.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -32768 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.35.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.35.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 32 54 53 52 33 38}
do_test boundary3-2.35.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.35.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -32768 ORDER BY t2.a
  }
} {1 2 11 21 29 37 44 47 55 58 63 64}
do_test boundary3-2.35.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -32768 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 29 21 11 2 1}
do_test boundary3-2.35.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.35.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.35.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.35.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.35.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.35.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -32768 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 55 58 63 64}
do_test boundary3-2.35.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -32768 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.35.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.35.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.35.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.35.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.35.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.oid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=2147483647 AND t2.a=t1.a
  }
} {20 000000007fffffff}
do_test boundary3-2.36.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000007fffffff'
  }
} {2147483647 20}
do_test boundary3-2.36.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=20
  }
} {2147483647 000000007fffffff}
do_test boundary3-2.36.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 2147483647 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.36.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 2147483647 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.36.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.36.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.36.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 2147483647 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.36.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 2147483647 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.36.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.36.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.36.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 2147483647 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.36.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 2147483647 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.36.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.36.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.36.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.36.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 2147483647 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.36.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 2147483647 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.36.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.36.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.36.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.36.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.oid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-129 AND t2.a=t1.a
  }
} {54 ffffffffffffff7f}
do_test boundary3-2.37.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffffff7f'
  }
} {-129 54}
do_test boundary3-2.37.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=54
  }
} {-129 ffffffffffffff7f}
do_test boundary3-2.37.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -129 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 56 57 59 60 61 62}
do_test boundary3-2.37.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -129 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.37.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.37.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 53 52 33 38}
do_test boundary3-2.37.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.37.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -129 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.37.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -129 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.37.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.37.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 54 53 52 33 38}
do_test boundary3-2.37.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.37.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -129 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 55 58 63 64}
do_test boundary3-2.37.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -129 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.37.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.37.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.37.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.37.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -129 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 54 55 58 63 64}
do_test boundary3-2.37.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -129 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.37.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.37.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.37.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.37.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.oid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-128 AND t2.a=t1.a
  }
} {53 ffffffffffffff80}
do_test boundary3-2.38.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffffff80'
  }
} {-128 53}
do_test boundary3-2.38.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=53
  }
} {-128 ffffffffffffff80}
do_test boundary3-2.38.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -128 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 56 57 59 60 61 62}
do_test boundary3-2.38.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -128 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.38.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.38.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 52 33 38}
do_test boundary3-2.38.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.38.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -128 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 56 57 59 60 61 62}
do_test boundary3-2.38.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -128 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.38.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.38.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 53 52 33 38}
do_test boundary3-2.38.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.38.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -128 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 54 55 58 63 64}
do_test boundary3-2.38.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -128 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.38.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.38.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.38.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.38.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -128 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 53 54 55 58 63 64}
do_test boundary3-2.38.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -128 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.38.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.38.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.38.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.38.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.oid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.39.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=72057594037927936 AND t2.a=t1.a
  }
} {28 0100000000000000}
do_test boundary3-2.39.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0100000000000000'
  }
} {72057594037927936 28}
do_test boundary3-2.39.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=28
  }
} {72057594037927936 0100000000000000}
do_test boundary3-2.39.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 72057594037927936 ORDER BY t2.a
  }
} {3}
do_test boundary3-2.39.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 72057594037927936 ORDER BY t1.a DESC
  }
} {3}
do_test boundary3-2.39.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=28
     ORDER BY t1.oid
  }
} {3}
do_test boundary3-2.39.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=28
     ORDER BY t1.oid DESC
  }
} {3}
do_test boundary3-2.39.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {3}
do_test boundary3-2.39.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 72057594037927936 ORDER BY t2.a
  }
} {3 28}
do_test boundary3-2.39.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 72057594037927936 ORDER BY t1.a DESC
  }
} {28 3}
do_test boundary3-2.39.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=28
     ORDER BY t1.oid
  }
} {28 3}
do_test boundary3-2.39.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=28
     ORDER BY t1.oid DESC
  }
} {3 28}
do_test boundary3-2.39.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {28 3}
do_test boundary3-2.39.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 72057594037927936 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.39.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 72057594037927936 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.39.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=28
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17}
do_test boundary3-2.39.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=28
     ORDER BY t1.oid DESC
  }
} {17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.39.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.39.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 72057594037927936 ORDER BY t2.a
  }
} {1 2 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}
do_test boundary3-2.39.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 72057594037927936 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.39.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=28
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28}
do_test boundary3-2.39.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=28
     ORDER BY t1.oid DESC
  }
} {28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.39.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.40.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=2147483648 AND t2.a=t1.a
  }
} {51 0000000080000000}
do_test boundary3-2.40.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000080000000'
  }
} {2147483648 51}
do_test boundary3-2.40.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=51
  }
} {2147483648 0000000080000000}
do_test boundary3-2.40.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 2147483648 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.40.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 2147483648 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.40.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.40.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.40.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 2147483648 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.40.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 2147483648 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.40.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.40.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.40.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 2147483648 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.40.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 2147483648 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.40.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.40.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.40.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.40.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.40.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.40.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 2147483648 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.40.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 2147483648 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.40.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.40.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.40.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.40.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.40.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.oid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=549755813887 AND t2.a=t1.a
  }
} {46 0000007fffffffff}
do_test boundary3-2.41.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000007fffffffff'
  }
} {549755813887 46}
do_test boundary3-2.41.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=46
  }
} {549755813887 0000007fffffffff}
do_test boundary3-2.41.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 549755813887 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 56 57}
do_test boundary3-2.41.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 549755813887 ORDER BY t1.a DESC
  }
} {57 56 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.41.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.41.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.41.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 549755813887 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.41.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 549755813887 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.41.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.41.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.41.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 549755813887 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.41.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 549755813887 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.41.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.41.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.41.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.41.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 549755813887 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.41.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 549755813887 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.41.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.41.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.41.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.41.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.oid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.42.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-549755813888 AND t2.a=t1.a
  }
} {63 ffffff8000000000}
do_test boundary3-2.42.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffff8000000000'
  }
} {-549755813888 63}
do_test boundary3-2.42.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=63
  }
} {-549755813888 ffffff8000000000}
do_test boundary3-2.42.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -549755813888 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.42.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -549755813888 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.42.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.42.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.42.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.42.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -549755813888 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62 63}
do_test boundary3-2.42.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -549755813888 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.42.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.42.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.42.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.42.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -549755813888 ORDER BY t2.a
  }
} {2 21 44 55 58 64}
do_test boundary3-2.42.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -549755813888 ORDER BY t1.a DESC
  }
} {64 58 55 44 21 2}
do_test boundary3-2.42.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.42.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.42.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {55 2 64 21 44 58}
do_test boundary3-2.42.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.42.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.42.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -549755813888 ORDER BY t2.a
  }
} {2 21 44 55 58 63 64}
do_test boundary3-2.42.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -549755813888 ORDER BY t1.a DESC
  }
} {64 63 58 55 44 21 2}
do_test boundary3-2.42.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.42.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.42.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.42.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.42.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.oid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.43.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=281474976710655 AND t2.a=t1.a
  }
} {10 0000ffffffffffff}
do_test boundary3-2.43.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000ffffffffffff'
  }
} {281474976710655 10}
do_test boundary3-2.43.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=10
  }
} {281474976710655 0000ffffffffffff}
do_test boundary3-2.43.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 281474976710655 ORDER BY t2.a
  }
} {3 13 17 26 27 28 43 45}
do_test boundary3-2.43.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 281474976710655 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 3}
do_test boundary3-2.43.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=10
     ORDER BY t1.oid
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.43.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=10
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26}
do_test boundary3-2.43.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.43.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 281474976710655 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 43 45}
do_test boundary3-2.43.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 281474976710655 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 10 3}
do_test boundary3-2.43.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=10
     ORDER BY t1.oid
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.43.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=10
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10}
do_test boundary3-2.43.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.43.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 281474976710655 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.43.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 281474976710655 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.43.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=10
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34}
do_test boundary3-2.43.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=10
     ORDER BY t1.oid DESC
  }
} {34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.43.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.43.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 281474976710655 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.43.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 281474976710655 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.43.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=10
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10}
do_test boundary3-2.43.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=10
     ORDER BY t1.oid DESC
  }
} {10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.43.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.44.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=4398046511103 AND t2.a=t1.a
  }
} {7 000003ffffffffff}
do_test boundary3-2.44.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000003ffffffffff'
  }
} {4398046511103 7}
do_test boundary3-2.44.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=7
  }
} {4398046511103 000003ffffffffff}
do_test boundary3-2.44.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 4398046511103 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.44.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 4398046511103 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.44.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.44.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.44.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 4398046511103 ORDER BY t2.a
  }
} {3 7 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.44.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 4398046511103 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 7 3}
do_test boundary3-2.44.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.44.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.44.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 4398046511103 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.44.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 4398046511103 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.44.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.44.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.44.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.44.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.44.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.44.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 4398046511103 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.44.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 4398046511103 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.44.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.44.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.44.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.44.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.44.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.oid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=268435455 AND t2.a=t1.a
  }
} {12 000000000fffffff}
do_test boundary3-2.45.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000000fffffff'
  }
} {268435455 12}
do_test boundary3-2.45.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=12
  }
} {268435455 000000000fffffff}
do_test boundary3-2.45.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 268435455 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.45.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 268435455 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.45.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.45.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.45.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 268435455 ORDER BY t2.a
  }
} {3 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.45.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 268435455 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 3}
do_test boundary3-2.45.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.45.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.45.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 268435455 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.45.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 268435455 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 6 5 4 2 1}
do_test boundary3-2.45.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.45.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.45.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.45.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 268435455 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.45.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 268435455 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.45.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.45.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.45.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.45.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.oid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.46.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-9223372036854775808 AND t2.a=t1.a
  }
} {55 8000000000000000}
do_test boundary3-2.46.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='8000000000000000'
  }
} {-9223372036854775808 55}
do_test boundary3-2.46.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=55
  }
} {-9223372036854775808 8000000000000000}
do_test boundary3-2.46.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -9223372036854775808 ORDER BY t2.a
  }
} {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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.46.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -9223372036854775808 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.46.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=55
     ORDER BY t1.oid
  }
} {2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.46.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=55
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2}
do_test boundary3-2.46.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.46.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -9223372036854775808 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.46.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -9223372036854775808 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.46.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=55
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.46.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=55
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.46.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.46.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -9223372036854775808 ORDER BY t2.a
  }
} {}
do_test boundary3-2.46.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -9223372036854775808 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.46.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=55
     ORDER BY t1.oid
  }
} {}
do_test boundary3-2.46.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=55
     ORDER BY t1.oid DESC
  }
} {}
do_test boundary3-2.46.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {}
do_test boundary3-2.46.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -9223372036854775808 ORDER BY t2.a
  }
} {55}
do_test boundary3-2.46.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -9223372036854775808 ORDER BY t1.a DESC
  }
} {55}
do_test boundary3-2.46.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=55
     ORDER BY t1.oid
  }
} {55}
do_test boundary3-2.46.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=55
     ORDER BY t1.oid DESC
  }
} {55}
do_test boundary3-2.46.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {55}
do_test boundary3-2.47.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=562949953421312 AND t2.a=t1.a
  }
} {43 0002000000000000}
do_test boundary3-2.47.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0002000000000000'
  }
} {562949953421312 43}
do_test boundary3-2.47.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=43
  }
} {562949953421312 0002000000000000}
do_test boundary3-2.47.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 562949953421312 ORDER BY t2.a
  }
} {3 17 27 28 45}
do_test boundary3-2.47.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 562949953421312 ORDER BY t1.a DESC
  }
} {45 28 27 17 3}
do_test boundary3-2.47.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=43
     ORDER BY t1.oid
  }
} {27 45 17 28 3}
do_test boundary3-2.47.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=43
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27}
do_test boundary3-2.47.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {27 45 17 28 3}
do_test boundary3-2.47.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 562949953421312 ORDER BY t2.a
  }
} {3 17 27 28 43 45}
do_test boundary3-2.47.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 562949953421312 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 3}
do_test boundary3-2.47.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=43
     ORDER BY t1.oid
  }
} {43 27 45 17 28 3}
do_test boundary3-2.47.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=43
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43}
do_test boundary3-2.47.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {43 27 45 17 28 3}
do_test boundary3-2.47.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 562949953421312 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.47.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 562949953421312 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.47.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=43
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13}
do_test boundary3-2.47.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=43
     ORDER BY t1.oid DESC
  }
} {13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.47.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.47.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 562949953421312 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.47.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 562949953421312 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.47.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=43
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43}
do_test boundary3-2.47.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=43
     ORDER BY t1.oid DESC
  }
} {43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.47.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.48.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-8388609 AND t2.a=t1.a
  }
} {1 ffffffffff7fffff}
do_test boundary3-2.48.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffff7fffff'
  }
} {-8388609 1}
do_test boundary3-2.48.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=1
  }
} {-8388609 ffffffffff7fffff}
do_test boundary3-2.48.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -8388609 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.48.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -8388609 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.48.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.48.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 37 29 32 54 53 52 33 38}
do_test boundary3-2.48.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.48.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -8388609 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.48.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -8388609 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.48.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.48.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.48.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.48.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -8388609 ORDER BY t2.a
  }
} {2 11 21 44 47 55 58 63 64}
do_test boundary3-2.48.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -8388609 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2}
do_test boundary3-2.48.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.48.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.48.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.48.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.48.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.48.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -8388609 ORDER BY t2.a
  }
} {1 2 11 21 44 47 55 58 63 64}
do_test boundary3-2.48.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -8388609 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2 1}
do_test boundary3-2.48.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.48.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.48.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.48.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.48.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.oid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=16777215 AND t2.a=t1.a
  }
} {9 0000000000ffffff}
do_test boundary3-2.49.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000ffffff'
  }
} {16777215 9}
do_test boundary3-2.49.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=9
  }
} {16777215 0000000000ffffff}
do_test boundary3-2.49.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 16777215 ORDER BY t2.a
  }
} {3 6 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.49.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 16777215 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 6 3}
do_test boundary3-2.49.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.49.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.49.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 16777215 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.49.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 16777215 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.49.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.49.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.49.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 16777215 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.49.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 16777215 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.49.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.49.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.49.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.49.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 16777215 ORDER BY t2.a
  }
} {1 2 4 5 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.49.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 16777215 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 5 4 2 1}
do_test boundary3-2.49.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.49.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.49.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.49.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.oid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=8388608 AND t2.a=t1.a
  }
} {24 0000000000800000}
do_test boundary3-2.50.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000800000'
  }
} {8388608 24}
do_test boundary3-2.50.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=24
  }
} {8388608 0000000000800000}
do_test boundary3-2.50.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 8388608 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.50.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 8388608 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.50.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.50.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.50.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 8388608 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.50.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 8388608 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.50.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.50.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.50.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 8388608 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.50.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 8388608 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.50.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.50.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.50.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.50.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 8388608 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.50.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 8388608 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.50.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.50.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.50.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.50.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.oid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=16383 AND t2.a=t1.a
  }
} {8 0000000000003fff}
do_test boundary3-2.51.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000003fff'
  }
} {16383 8}
do_test boundary3-2.51.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=8
  }
} {16383 0000000000003fff}
do_test boundary3-2.51.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 16383 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.51.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 16383 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.51.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.51.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.51.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 16383 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.51.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 16383 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.51.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.51.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.51.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 16383 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.51.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 16383 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.51.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.51.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.51.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.51.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 16383 ORDER BY t2.a
  }
} {1 2 4 5 8 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.51.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 16383 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 8 5 4 2 1}
do_test boundary3-2.51.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.51.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.51.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.51.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.oid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.52.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=140737488355328 AND t2.a=t1.a
  }
} {34 0000800000000000}
do_test boundary3-2.52.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000800000000000'
  }
} {140737488355328 34}
do_test boundary3-2.52.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=34
  }
} {140737488355328 0000800000000000}
do_test boundary3-2.52.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 140737488355328 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 43 45}
do_test boundary3-2.52.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 140737488355328 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 10 3}
do_test boundary3-2.52.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=34
     ORDER BY t1.oid
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=34
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10}
do_test boundary3-2.52.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 140737488355328 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 34 43 45}
do_test boundary3-2.52.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 140737488355328 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 17 13 10 3}
do_test boundary3-2.52.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=34
     ORDER BY t1.oid
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=34
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34}
do_test boundary3-2.52.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 140737488355328 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.52.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 140737488355328 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.52.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=34
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25}
do_test boundary3-2.52.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=34
     ORDER BY t1.oid DESC
  }
} {25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.52.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.52.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 140737488355328 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.52.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 140737488355328 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.52.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=34
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34}
do_test boundary3-2.52.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=34
     ORDER BY t1.oid DESC
  }
} {34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.52.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.53.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=2097151 AND t2.a=t1.a
  }
} {15 00000000001fffff}
do_test boundary3-2.53.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000001fffff'
  }
} {2097151 15}
do_test boundary3-2.53.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=15
  }
} {2097151 00000000001fffff}
do_test boundary3-2.53.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 2097151 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.53.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 2097151 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.53.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.53.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.53.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 2097151 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.53.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 2097151 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.53.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.53.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.53.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 2097151 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.53.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 2097151 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.53.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.53.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.53.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.53.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.53.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.53.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 2097151 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.53.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 2097151 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.53.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.53.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.53.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.53.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.53.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.oid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.54.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=140737488355327 AND t2.a=t1.a
  }
} {25 00007fffffffffff}
do_test boundary3-2.54.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00007fffffffffff'
  }
} {140737488355327 25}
do_test boundary3-2.54.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=25
  }
} {140737488355327 00007fffffffffff}
do_test boundary3-2.54.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 140737488355327 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 34 43 45}
do_test boundary3-2.54.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 140737488355327 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 17 13 10 3}
do_test boundary3-2.54.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=25
     ORDER BY t1.oid
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=25
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34}
do_test boundary3-2.54.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 140737488355327 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45}
do_test boundary3-2.54.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 140737488355327 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.54.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=25
     ORDER BY t1.oid
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=25
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25}
do_test boundary3-2.54.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 140737488355327 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.54.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 140737488355327 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.54.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=25
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56}
do_test boundary3-2.54.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=25
     ORDER BY t1.oid DESC
  }
} {56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.54.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.54.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 140737488355327 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.54.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 140737488355327 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.54.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=25
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25}
do_test boundary3-2.54.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=25
     ORDER BY t1.oid DESC
  }
} {25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.54.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.55.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=281474976710656 AND t2.a=t1.a
  }
} {26 0001000000000000}
do_test boundary3-2.55.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0001000000000000'
  }
} {281474976710656 26}
do_test boundary3-2.55.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=26
  }
} {281474976710656 0001000000000000}
do_test boundary3-2.55.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 281474976710656 ORDER BY t2.a
  }
} {3 13 17 27 28 43 45}
do_test boundary3-2.55.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 281474976710656 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 13 3}
do_test boundary3-2.55.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=26
     ORDER BY t1.oid
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.55.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=26
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13}
do_test boundary3-2.55.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.55.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 281474976710656 ORDER BY t2.a
  }
} {3 13 17 26 27 28 43 45}
do_test boundary3-2.55.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 281474976710656 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 3}
do_test boundary3-2.55.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=26
     ORDER BY t1.oid
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.55.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=26
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26}
do_test boundary3-2.55.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.55.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 281474976710656 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.55.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 281474976710656 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.55.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=26
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10}
do_test boundary3-2.55.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=26
     ORDER BY t1.oid DESC
  }
} {10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.55.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.55.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 281474976710656 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.55.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 281474976710656 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.55.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=26
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26}
do_test boundary3-2.55.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=26
     ORDER BY t1.oid DESC
  }
} {26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.55.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.56.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=32767 AND t2.a=t1.a
  }
} {23 0000000000007fff}
do_test boundary3-2.56.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000007fff'
  }
} {32767 23}
do_test boundary3-2.56.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=23
  }
} {32767 0000000000007fff}
do_test boundary3-2.56.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 32767 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.56.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 32767 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.56.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.56.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.56.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 32767 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.56.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 32767 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.56.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.56.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.56.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 32767 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.56.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 32767 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 16 11 8 5 4 2 1}
do_test boundary3-2.56.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.56.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.56.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.56.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.56.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.56.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 32767 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.56.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 32767 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.56.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.56.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.56.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.56.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.56.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.oid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=127 AND t2.a=t1.a
  }
} {4 000000000000007f}
do_test boundary3-2.57.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000000000007f'
  }
} {127 4}
do_test boundary3-2.57.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=4
  }
} {127 000000000000007f}
do_test boundary3-2.57.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 127 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.57.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 127 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.57.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.57.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.57.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 127 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.57.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 127 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.57.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.57.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.57.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 127 ORDER BY t2.a
  }
} {1 2 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.57.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 127 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 2 1}
do_test boundary3-2.57.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.57.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {59 60 41 5 31 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.57.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.57.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 127 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.57.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 127 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.57.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.57.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {59 60 41 5 31 4 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.57.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.57.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.oid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.58.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=36028797018963967 AND t2.a=t1.a
  }
} {27 007fffffffffffff}
do_test boundary3-2.58.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='007fffffffffffff'
  }
} {36028797018963967 27}
do_test boundary3-2.58.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=27
  }
} {36028797018963967 007fffffffffffff}
do_test boundary3-2.58.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 36028797018963967 ORDER BY t2.a
  }
} {3 17 28 45}
do_test boundary3-2.58.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 36028797018963967 ORDER BY t1.a DESC
  }
} {45 28 17 3}
do_test boundary3-2.58.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=27
     ORDER BY t1.oid
  }
} {45 17 28 3}
do_test boundary3-2.58.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=27
     ORDER BY t1.oid DESC
  }
} {3 28 17 45}
do_test boundary3-2.58.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {45 17 28 3}
do_test boundary3-2.58.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 36028797018963967 ORDER BY t2.a
  }
} {3 17 27 28 45}
do_test boundary3-2.58.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 36028797018963967 ORDER BY t1.a DESC
  }
} {45 28 27 17 3}
do_test boundary3-2.58.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=27
     ORDER BY t1.oid
  }
} {27 45 17 28 3}
do_test boundary3-2.58.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=27
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27}
do_test boundary3-2.58.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {27 45 17 28 3}
do_test boundary3-2.58.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 36028797018963967 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.58.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 36028797018963967 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.58.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=27
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43}
do_test boundary3-2.58.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=27
     ORDER BY t1.oid DESC
  }
} {43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.58.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.58.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 36028797018963967 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.58.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 36028797018963967 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.58.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=27
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27}
do_test boundary3-2.58.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=27
     ORDER BY t1.oid DESC
  }
} {27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.58.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.59.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=4398046511104 AND t2.a=t1.a
  }
} {56 0000040000000000}
do_test boundary3-2.59.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000040000000000'
  }
} {4398046511104 56}
do_test boundary3-2.59.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=56
  }
} {4398046511104 0000040000000000}
do_test boundary3-2.59.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 4398046511104 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45}
do_test boundary3-2.59.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 4398046511104 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.59.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25}
do_test boundary3-2.59.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25}
do_test boundary3-2.59.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 4398046511104 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.59.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 4398046511104 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.59.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.59.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.59.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 4398046511104 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.59.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 4398046511104 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.59.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.59.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.59.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.59.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.59.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.59.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 4398046511104 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.59.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 4398046511104 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.59.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56}
do_test boundary3-2.59.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.59.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.59.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56}
do_test boundary3-2.59.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.oid DESC
  }
} {56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=1 AND t2.a=t1.a
  }
} {60 0000000000000001}
do_test boundary3-2.60.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000001'
  }
} {1 60}
do_test boundary3-2.60.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=60
  }
} {1 0000000000000001}
do_test boundary3-2.60.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.60.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 1 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.60.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.60.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.60.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 60 61 62}
do_test boundary3-2.60.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 1 ORDER BY t1.a DESC
  }
} {62 61 60 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.60.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.60.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.60.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 63 64}
do_test boundary3-2.60.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 1 ORDER BY t1.a DESC
  }
} {64 63 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.60.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.60.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {59 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.60.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.60.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.60.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 1 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.60.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.60.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {59 60 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.60.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.60.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.oid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.61.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=36028797018963968 AND t2.a=t1.a
  }
} {45 0080000000000000}
do_test boundary3-2.61.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0080000000000000'
  }
} {36028797018963968 45}
do_test boundary3-2.61.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=45
  }
} {36028797018963968 0080000000000000}
do_test boundary3-2.61.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 36028797018963968 ORDER BY t2.a
  }
} {3 17 28}
do_test boundary3-2.61.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 36028797018963968 ORDER BY t1.a DESC
  }
} {28 17 3}
do_test boundary3-2.61.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=45
     ORDER BY t1.oid
  }
} {17 28 3}
do_test boundary3-2.61.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=45
     ORDER BY t1.oid DESC
  }
} {3 28 17}
do_test boundary3-2.61.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {17 28 3}
do_test boundary3-2.61.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 36028797018963968 ORDER BY t2.a
  }
} {3 17 28 45}
do_test boundary3-2.61.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 36028797018963968 ORDER BY t1.a DESC
  }
} {45 28 17 3}
do_test boundary3-2.61.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=45
     ORDER BY t1.oid
  }
} {45 17 28 3}
do_test boundary3-2.61.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=45
     ORDER BY t1.oid DESC
  }
} {3 28 17 45}
do_test boundary3-2.61.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {45 17 28 3}
do_test boundary3-2.61.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 36028797018963968 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.61.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 36028797018963968 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.61.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=45
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27}
do_test boundary3-2.61.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=45
     ORDER BY t1.oid DESC
  }
} {27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.61.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.61.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 36028797018963968 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.61.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 36028797018963968 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.61.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=45
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45}
do_test boundary3-2.61.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=45
     ORDER BY t1.oid DESC
  }
} {45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.61.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.62.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-2147483649 AND t2.a=t1.a
  }
} {47 ffffffff7fffffff}
do_test boundary3-2.62.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffff7fffffff'
  }
} {-2147483649 47}
do_test boundary3-2.62.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=47
  }
} {-2147483649 ffffffff7fffffff}
do_test boundary3-2.62.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -2147483649 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.62.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -2147483649 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.62.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.62.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.62.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.62.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -2147483649 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.62.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -2147483649 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.62.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.62.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.62.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.62.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -2147483649 ORDER BY t2.a
  }
} {2 21 44 55 58 63 64}
do_test boundary3-2.62.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -2147483649 ORDER BY t1.a DESC
  }
} {64 63 58 55 44 21 2}
do_test boundary3-2.62.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.62.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.62.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.62.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.62.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.62.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -2147483649 ORDER BY t2.a
  }
} {2 21 44 47 55 58 63 64}
do_test boundary3-2.62.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -2147483649 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 2}
do_test boundary3-2.62.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.62.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.62.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.62.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.62.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.oid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.63.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=-36028797018963969 AND t2.a=t1.a
  }
} {2 ff7fffffffffffff}
do_test boundary3-2.63.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ff7fffffffffffff'
  }
} {-36028797018963969 2}
do_test boundary3-2.63.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=2
  }
} {-36028797018963969 ff7fffffffffffff}
do_test boundary3-2.63.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -36028797018963969 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.63.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -36028797018963969 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.63.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=2
     ORDER BY t1.oid
  }
} {64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.63.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=2
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64}
do_test boundary3-2.63.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.63.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -36028797018963969 ORDER BY t2.a
  }
} {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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.63.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -36028797018963969 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.63.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=2
     ORDER BY t1.oid
  }
} {2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.63.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=2
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2}
do_test boundary3-2.63.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.63.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -36028797018963969 ORDER BY t2.a
  }
} {55}
do_test boundary3-2.63.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -36028797018963969 ORDER BY t1.a DESC
  }
} {55}
do_test boundary3-2.63.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=2
     ORDER BY t1.oid
  }
} {55}
do_test boundary3-2.63.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=2
     ORDER BY t1.oid DESC
  }
} {55}
do_test boundary3-2.63.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {55}
do_test boundary3-2.63.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -36028797018963969 ORDER BY t2.a
  }
} {2 55}
do_test boundary3-2.63.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -36028797018963969 ORDER BY t1.a DESC
  }
} {55 2}
do_test boundary3-2.63.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=2
     ORDER BY t1.oid
  }
} {55 2}
do_test boundary3-2.63.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=2
     ORDER BY t1.oid DESC
  }
} {2 55}
do_test boundary3-2.63.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {55 2}
do_test boundary3-2.64.1 {
  db eval {
    SELECT t1.a,t1.x FROM t1, t2 WHERE t1.oid=3 AND t2.a=t1.a
  }
} {5 0000000000000003}
do_test boundary3-2.64.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000003'
  }
} {3 5}
do_test boundary3-2.64.3 {
  db eval {
    SELECT t1.oid, x FROM t1 JOIN t2 ON t2.r=t1.oid WHERE t2.a=5
  }
} {3 0000000000000003}
do_test boundary3-2.64.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 3 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.64.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 3 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.64.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.64.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.64.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 3 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.64.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 3 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.64.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.64.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.64.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 3 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.64.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 3 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.64.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.64.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.64.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {59 60 41 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.64.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.64.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.64.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 3 ORDER BY t2.a
  }
} {1 2 5 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.64.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 3 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 5 2 1}
do_test boundary3-2.64.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.64.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.64.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {59 60 41 5 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.64.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.64.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.oid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.65.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.65.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.65.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=65
     ORDER BY t1.oid
  }
} {}
do_test boundary3-2.65.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=65
     ORDER BY t1.oid DESC
  }
} {}
do_test boundary3-2.65.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {}
do_test boundary3-2.65.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.65.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.65.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=65
     ORDER BY t1.oid
  }
} {}
do_test boundary3-2.65.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=65
     ORDER BY t1.oid DESC
  }
} {}
do_test boundary3-2.65.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {}
do_test boundary3-2.65.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.65.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.65.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=65
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.65.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=65
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.65.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.65.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.65.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.65.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=65
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.65.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=65
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.65.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.66.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid > -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.66.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid > -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.66.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=66
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.66.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=66
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.66.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid > t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.66.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid >= -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.66.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid >= -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.66.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=66
     ORDER BY t1.oid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.66.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=66
     ORDER BY t1.oid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.66.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid >= t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.66.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid < -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.66.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid < -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.66.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=66
     ORDER BY t1.oid
  }
} {}
do_test boundary3-2.66.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=66
     ORDER BY t1.oid DESC
  }
} {}
do_test boundary3-2.66.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid < t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {}
do_test boundary3-2.66.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.oid <= -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.66.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.oid <= -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.66.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=66
     ORDER BY t1.oid
  }
} {}
do_test boundary3-2.66.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=66
     ORDER BY t1.oid DESC
  }
} {}
do_test boundary3-2.66.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.oid <= t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {}
finish_test







|









|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|




|









|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|






|









|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|






|

|




|

|





|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|







|





|




|

|




|

|




|





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
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
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
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
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
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
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
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
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
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
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
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
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
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
2321
2322
2323
2324
2325
2326
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
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
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
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
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
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
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
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
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
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
2706
2707
2708
2709
2710
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
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
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
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
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
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
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
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
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
3188
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
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
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
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
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
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
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
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
3660
3661
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
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
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
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
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
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
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
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
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
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
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
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
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
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
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
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
  db eval {
    SELECT count(*) FROM t1
  }
} {64}
do_test boundary3-1.3 {
  db eval {
    CREATE TABLE t2(r,a);
    INSERT INTO t2 SELECT rowid, a FROM t1;
    CREATE INDEX t2i1 ON t2(r);
    CREATE INDEX t2i2 ON t2(a);
    INSERT INTO t2 VALUES(9.22337303685477580800e+18,65);
    INSERT INTO t2 VALUES(-9.22337303685477580800e+18,66);
    SELECT count(*) FROM t2;
  }
} {66}
do_test boundary3-2.1.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=72057594037927935 AND t2.a=t1.a
  }
} {17 00ffffffffffffff}
do_test boundary3-2.1.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00ffffffffffffff'
  }
} {72057594037927935 17}
do_test boundary3-2.1.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=17
  }
} {72057594037927935 00ffffffffffffff}
do_test boundary3-2.1.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 72057594037927935 ORDER BY t2.a
  }
} {3 28}
do_test boundary3-2.1.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 72057594037927935 ORDER BY t1.a DESC
  }
} {28 3}
do_test boundary3-2.1.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid
  }
} {28 3}
do_test boundary3-2.1.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid DESC
  }
} {3 28}
do_test boundary3-2.1.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {28 3}
do_test boundary3-2.1.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 72057594037927935 ORDER BY t2.a
  }
} {3 17 28}
do_test boundary3-2.1.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 72057594037927935 ORDER BY t1.a DESC
  }
} {28 17 3}
do_test boundary3-2.1.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid
  }
} {17 28 3}
do_test boundary3-2.1.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid DESC
  }
} {3 28 17}
do_test boundary3-2.1.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {17 28 3}
do_test boundary3-2.1.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 72057594037927935 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.1.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 72057594037927935 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.1.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45}
do_test boundary3-2.1.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid DESC
  }
} {45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.1.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.1.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 72057594037927935 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.1.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 72057594037927935 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.1.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17}
do_test boundary3-2.1.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=17
     ORDER BY t1.rowid DESC
  }
} {17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.1.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=17
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.2.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=16384 AND t2.a=t1.a
  }
} {16 0000000000004000}
do_test boundary3-2.2.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000004000'
  }
} {16384 16}
do_test boundary3-2.2.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=16
  }
} {16384 0000000000004000}
do_test boundary3-2.2.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 16384 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.2.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 16384 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.2.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.2.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.2.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 16384 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.2.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 16384 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.2.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.2.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.2.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.2.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 16384 ORDER BY t2.a
  }
} {1 2 4 5 8 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.2.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 16384 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 8 5 4 2 1}
do_test boundary3-2.2.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.2.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.2.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.2.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.2.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.2.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 16384 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.2.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 16384 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 16 11 8 5 4 2 1}
do_test boundary3-2.2.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.2.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.2.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=16
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.2.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.2.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=16
     ORDER BY t1.rowid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=4294967296 AND t2.a=t1.a
  }
} {36 0000000100000000}
do_test boundary3-2.3.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000100000000'
  }
} {4294967296 36}
do_test boundary3-2.3.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=36
  }
} {4294967296 0000000100000000}
do_test boundary3-2.3.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 4294967296 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 39 43 45 46 56 57}
do_test boundary3-2.3.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 4294967296 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.3.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.3.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.3.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 4294967296 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.3.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 4294967296 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.3.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.3.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.3.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.3.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 4294967296 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.3.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 4294967296 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.3.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.3.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.3.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.3.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 4294967296 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.3.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 4294967296 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.3.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.3.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.3.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=36
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.3.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.3.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=36
     ORDER BY t1.rowid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=16777216 AND t2.a=t1.a
  }
} {6 0000000001000000}
do_test boundary3-2.4.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000001000000'
  }
} {16777216 6}
do_test boundary3-2.4.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=6
  }
} {16777216 0000000001000000}
do_test boundary3-2.4.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 16777216 ORDER BY t2.a
  }
} {3 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.4.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 16777216 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 3}
do_test boundary3-2.4.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.4.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.4.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 16777216 ORDER BY t2.a
  }
} {3 6 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.4.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 16777216 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 6 3}
do_test boundary3-2.4.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.4.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.4.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.4.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 16777216 ORDER BY t2.a
  }
} {1 2 4 5 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.4.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 16777216 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 5 4 2 1}
do_test boundary3-2.4.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.4.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.4.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.4.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 16777216 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.4.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 16777216 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 6 5 4 2 1}
do_test boundary3-2.4.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.4.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.4.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=6
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.4.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.4.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=6
     ORDER BY t1.rowid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-32769 AND t2.a=t1.a
  }
} {29 ffffffffffff7fff}
do_test boundary3-2.5.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffff7fff'
  }
} {-32769 29}
do_test boundary3-2.5.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=29
  }
} {-32769 ffffffffffff7fff}
do_test boundary3-2.5.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -32769 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.5.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -32769 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.5.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.5.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 32 54 53 52 33 38}
do_test boundary3-2.5.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.5.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -32769 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.5.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -32769 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.5.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.5.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 29 32 54 53 52 33 38}
do_test boundary3-2.5.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.5.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.5.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -32769 ORDER BY t2.a
  }
} {1 2 11 21 37 44 47 55 58 63 64}
do_test boundary3-2.5.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -32769 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 21 11 2 1}
do_test boundary3-2.5.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.5.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.5.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.5.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -32769 ORDER BY t2.a
  }
} {1 2 11 21 29 37 44 47 55 58 63 64}
do_test boundary3-2.5.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -32769 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 29 21 11 2 1}
do_test boundary3-2.5.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.5.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.5.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=29
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.5.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.5.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=29
     ORDER BY t1.rowid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.6.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-140737488355329 AND t2.a=t1.a
  }
} {21 ffff7fffffffffff}
do_test boundary3-2.6.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffff7fffffffffff'
  }
} {-140737488355329 21}
do_test boundary3-2.6.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=21
  }
} {-140737488355329 ffff7fffffffffff}
do_test boundary3-2.6.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -140737488355329 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.6.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -140737488355329 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.6.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid
  }
} {44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.6.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44}
do_test boundary3-2.6.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.6.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -140737488355329 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.6.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -140737488355329 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.6.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid
  }
} {21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.6.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21}
do_test boundary3-2.6.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.6.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -140737488355329 ORDER BY t2.a
  }
} {2 55 64}
do_test boundary3-2.6.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -140737488355329 ORDER BY t1.a DESC
  }
} {64 55 2}
do_test boundary3-2.6.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid
  }
} {55 2 64}
do_test boundary3-2.6.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid DESC
  }
} {64 2 55}
do_test boundary3-2.6.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {55 2 64}
do_test boundary3-2.6.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -140737488355329 ORDER BY t2.a
  }
} {2 21 55 64}
do_test boundary3-2.6.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -140737488355329 ORDER BY t1.a DESC
  }
} {64 55 21 2}
do_test boundary3-2.6.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid
  }
} {55 2 64 21}
do_test boundary3-2.6.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=21
     ORDER BY t1.rowid DESC
  }
} {21 64 2 55}
do_test boundary3-2.6.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=21
     ORDER BY x
  }
} {55 2 64 21}
do_test boundary3-2.7.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=2 AND t2.a=t1.a
  }
} {41 0000000000000002}
do_test boundary3-2.7.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000002'
  }
} {2 41}
do_test boundary3-2.7.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=41
  }
} {2 0000000000000002}
do_test boundary3-2.7.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.7.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 2 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.7.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.7.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.7.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.7.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 2 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.7.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.7.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.7.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.7.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.7.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 2 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.7.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.7.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.7.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {59 60 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.7.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.7.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.7.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.7.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 2 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.7.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.7.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.7.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=41
     ORDER BY x
  }
} {59 60 41 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.7.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.7.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=41
     ORDER BY t1.rowid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=4 AND t2.a=t1.a
  }
} {31 0000000000000004}
do_test boundary3-2.8.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000004'
  }
} {4 31}
do_test boundary3-2.8.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=31
  }
} {4 0000000000000004}
do_test boundary3-2.8.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 4 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.8.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 4 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.8.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.8.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.8.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 4 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.8.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 4 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.8.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.8.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.8.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.8.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 4 ORDER BY t2.a
  }
} {1 2 5 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.8.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 4 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 5 2 1}
do_test boundary3-2.8.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.8.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {59 60 41 5 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.8.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.8.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 4 ORDER BY t2.a
  }
} {1 2 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.8.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 4 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 2 1}
do_test boundary3-2.8.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.8.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.8.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=31
     ORDER BY x
  }
} {59 60 41 5 31 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.8.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.8.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=31
     ORDER BY t1.rowid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.9.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=562949953421311 AND t2.a=t1.a
  }
} {13 0001ffffffffffff}
do_test boundary3-2.9.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0001ffffffffffff'
  }
} {562949953421311 13}
do_test boundary3-2.9.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=13
  }
} {562949953421311 0001ffffffffffff}
do_test boundary3-2.9.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 562949953421311 ORDER BY t2.a
  }
} {3 17 27 28 43 45}
do_test boundary3-2.9.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 562949953421311 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 3}
do_test boundary3-2.9.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid
  }
} {43 27 45 17 28 3}
do_test boundary3-2.9.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43}
do_test boundary3-2.9.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {43 27 45 17 28 3}
do_test boundary3-2.9.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 562949953421311 ORDER BY t2.a
  }
} {3 13 17 27 28 43 45}
do_test boundary3-2.9.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 562949953421311 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 13 3}
do_test boundary3-2.9.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.9.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13}
do_test boundary3-2.9.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.9.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 562949953421311 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.9.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 562949953421311 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.9.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26}
do_test boundary3-2.9.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid DESC
  }
} {26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.9.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.9.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 562949953421311 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.9.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 562949953421311 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.9.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13}
do_test boundary3-2.9.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=13
     ORDER BY t1.rowid DESC
  }
} {13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.9.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=13
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.10.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=256 AND t2.a=t1.a
  }
} {61 0000000000000100}
do_test boundary3-2.10.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000100'
  }
} {256 61}
do_test boundary3-2.10.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=61
  }
} {256 0000000000000100}
do_test boundary3-2.10.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 256 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.10.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 256 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.10.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.10.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.10.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 256 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.10.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 256 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.10.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.10.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.10.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.10.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 256 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.10.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 256 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.10.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.10.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.10.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.10.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.10.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.10.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 256 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.10.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 256 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.10.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.10.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.10.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=61
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.10.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.10.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=61
     ORDER BY t1.rowid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=34359738368 AND t2.a=t1.a
  }
} {22 0000000800000000}
do_test boundary3-2.11.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000800000000'
  }
} {34359738368 22}
do_test boundary3-2.11.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=22
  }
} {34359738368 0000000800000000}
do_test boundary3-2.11.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 34359738368 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.11.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 34359738368 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.11.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.11.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.11.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 34359738368 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.11.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 34359738368 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.11.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.11.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.11.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.11.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 34359738368 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.11.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 34359738368 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.11.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.11.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.11.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.11.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 34359738368 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.11.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 34359738368 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.11.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.11.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.11.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=22
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.11.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.11.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=22
     ORDER BY t1.rowid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=65536 AND t2.a=t1.a
  }
} {62 0000000000010000}
do_test boundary3-2.12.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000010000'
  }
} {65536 62}
do_test boundary3-2.12.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=62
  }
} {65536 0000000000010000}
do_test boundary3-2.12.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 65536 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.12.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 65536 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.12.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.12.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.12.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 65536 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57 62}
do_test boundary3-2.12.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 65536 ORDER BY t1.a DESC
  }
} {62 57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.12.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.12.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.12.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.12.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 65536 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.12.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 65536 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.12.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.12.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.12.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.12.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 65536 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.12.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 65536 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.12.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.12.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.12.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=62
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.12.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.12.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=62
     ORDER BY t1.rowid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=268435456 AND t2.a=t1.a
  }
} {40 0000000010000000}
do_test boundary3-2.13.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000010000000'
  }
} {268435456 40}
do_test boundary3-2.13.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=40
  }
} {268435456 0000000010000000}
do_test boundary3-2.13.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 268435456 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.13.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 268435456 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.13.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.13.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.13.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 268435456 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.13.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 268435456 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.13.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.13.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.13.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.13.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 268435456 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.13.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 268435456 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.13.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.13.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.13.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.13.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 268435456 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.13.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 268435456 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.13.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.13.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.13.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=40
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.13.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.13.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=40
     ORDER BY t1.rowid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.14.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-140737488355328 AND t2.a=t1.a
  }
} {44 ffff800000000000}
do_test boundary3-2.14.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffff800000000000'
  }
} {-140737488355328 44}
do_test boundary3-2.14.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=44
  }
} {-140737488355328 ffff800000000000}
do_test boundary3-2.14.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -140737488355328 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 58 59 60 61 62 63}
do_test boundary3-2.14.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -140737488355328 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.14.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid
  }
} {58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.14.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58}
do_test boundary3-2.14.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.14.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -140737488355328 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.14.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -140737488355328 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.14.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid
  }
} {44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.14.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44}
do_test boundary3-2.14.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.14.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -140737488355328 ORDER BY t2.a
  }
} {2 21 55 64}
do_test boundary3-2.14.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -140737488355328 ORDER BY t1.a DESC
  }
} {64 55 21 2}
do_test boundary3-2.14.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid
  }
} {55 2 64 21}
do_test boundary3-2.14.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid DESC
  }
} {21 64 2 55}
do_test boundary3-2.14.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {55 2 64 21}
do_test boundary3-2.14.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -140737488355328 ORDER BY t2.a
  }
} {2 21 44 55 64}
do_test boundary3-2.14.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -140737488355328 ORDER BY t1.a DESC
  }
} {64 55 44 21 2}
do_test boundary3-2.14.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid
  }
} {55 2 64 21 44}
do_test boundary3-2.14.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=44
     ORDER BY t1.rowid DESC
  }
} {44 21 64 2 55}
do_test boundary3-2.14.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=44
     ORDER BY x
  }
} {55 2 64 21 44}
do_test boundary3-2.15.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=1099511627776 AND t2.a=t1.a
  }
} {19 0000010000000000}
do_test boundary3-2.15.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000010000000000'
  }
} {1099511627776 19}
do_test boundary3-2.15.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=19
  }
} {1099511627776 0000010000000000}
do_test boundary3-2.15.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 1099511627776 ORDER BY t2.a
  }
} {3 7 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.15.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 1099511627776 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 7 3}
do_test boundary3-2.15.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.15.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.15.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 1099511627776 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56}
do_test boundary3-2.15.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 1099511627776 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.15.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.15.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.15.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.15.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 1099511627776 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.15.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 1099511627776 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.15.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.15.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.15.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.15.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.15.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.15.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 1099511627776 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.15.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 1099511627776 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.15.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.15.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.15.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=19
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.15.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.15.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=19
     ORDER BY t1.rowid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.16.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 9223372036854775807 ORDER BY t2.a
  }
} {}
do_test boundary3-2.16.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 9223372036854775807 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.16.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid
  }
} {}
do_test boundary3-2.16.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid DESC
  }
} {}
do_test boundary3-2.16.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {}
do_test boundary3-2.16.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 9223372036854775807 ORDER BY t2.a
  }
} {3}
do_test boundary3-2.16.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 9223372036854775807 ORDER BY t1.a DESC
  }
} {3}
do_test boundary3-2.16.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid
  }
} {3}
do_test boundary3-2.16.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid DESC
  }
} {3}
do_test boundary3-2.16.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {3}
do_test boundary3-2.16.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 9223372036854775807 ORDER BY t2.a
  }
} {1 2 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}
do_test boundary3-2.16.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 9223372036854775807 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.16.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28}
do_test boundary3-2.16.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid DESC
  }
} {28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.16.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.16.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 9223372036854775807 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.16.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 9223372036854775807 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.16.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.16.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=3
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.16.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=3
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.17.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=32768 AND t2.a=t1.a
  }
} {50 0000000000008000}
do_test boundary3-2.17.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000008000'
  }
} {32768 50}
do_test boundary3-2.17.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=50
  }
} {32768 0000000000008000}
do_test boundary3-2.17.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 32768 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 51 56 57 62}
do_test boundary3-2.17.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 32768 ORDER BY t1.a DESC
  }
} {62 57 56 51 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.17.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.17.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.17.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 32768 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.17.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 32768 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.17.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.17.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.17.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.17.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 32768 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.17.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 32768 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.17.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.17.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.17.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.17.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.17.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.17.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 32768 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.17.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 32768 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.17.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.17.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.17.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=50
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.17.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.17.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=50
     ORDER BY t1.rowid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.18.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-36028797018963968 AND t2.a=t1.a
  }
} {64 ff80000000000000}
do_test boundary3-2.18.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ff80000000000000'
  }
} {-36028797018963968 64}
do_test boundary3-2.18.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=64
  }
} {-36028797018963968 ff80000000000000}
do_test boundary3-2.18.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -36028797018963968 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63}
do_test boundary3-2.18.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -36028797018963968 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.18.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid
  }
} {21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.18.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21}
do_test boundary3-2.18.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.18.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -36028797018963968 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.18.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -36028797018963968 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.18.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid
  }
} {64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.18.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64}
do_test boundary3-2.18.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.18.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -36028797018963968 ORDER BY t2.a
  }
} {2 55}
do_test boundary3-2.18.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -36028797018963968 ORDER BY t1.a DESC
  }
} {55 2}
do_test boundary3-2.18.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid
  }
} {55 2}
do_test boundary3-2.18.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid DESC
  }
} {2 55}
do_test boundary3-2.18.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {55 2}
do_test boundary3-2.18.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -36028797018963968 ORDER BY t2.a
  }
} {2 55 64}
do_test boundary3-2.18.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -36028797018963968 ORDER BY t1.a DESC
  }
} {64 55 2}
do_test boundary3-2.18.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid
  }
} {55 2 64}
do_test boundary3-2.18.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=64
     ORDER BY t1.rowid DESC
  }
} {64 2 55}
do_test boundary3-2.18.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=64
     ORDER BY x
  }
} {55 2 64}
do_test boundary3-2.19.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=65535 AND t2.a=t1.a
  }
} {48 000000000000ffff}
do_test boundary3-2.19.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000000000ffff'
  }
} {65535 48}
do_test boundary3-2.19.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=48
  }
} {65535 000000000000ffff}
do_test boundary3-2.19.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 65535 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57 62}
do_test boundary3-2.19.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 65535 ORDER BY t1.a DESC
  }
} {62 57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.19.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.19.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62}
do_test boundary3-2.19.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 65535 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 51 56 57 62}
do_test boundary3-2.19.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 65535 ORDER BY t1.a DESC
  }
} {62 57 56 51 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.19.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.19.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.19.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48}
do_test boundary3-2.19.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 65535 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.19.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 65535 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.19.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.19.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.19.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.19.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50}
do_test boundary3-2.19.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.19.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 65535 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.19.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 65535 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.19.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.19.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.19.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=48
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.19.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48}
do_test boundary3-2.19.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=48
     ORDER BY t1.rowid DESC
  }
} {48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=4294967295 AND t2.a=t1.a
  }
} {14 00000000ffffffff}
do_test boundary3-2.20.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000ffffffff'
  }
} {4294967295 14}
do_test boundary3-2.20.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=14
  }
} {4294967295 00000000ffffffff}
do_test boundary3-2.20.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 4294967295 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.20.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 4294967295 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.20.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.20.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36}
do_test boundary3-2.20.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 4294967295 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.20.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 4294967295 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.20.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.20.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.20.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.20.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 4294967295 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.20.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 4294967295 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.20.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.20.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.20.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.20.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 4294967295 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.20.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 4294967295 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.20.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.20.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.20.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=14
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.20.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14}
do_test boundary3-2.20.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=14
     ORDER BY t1.rowid DESC
  }
} {14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=1099511627775 AND t2.a=t1.a
  }
} {57 000000ffffffffff}
do_test boundary3-2.21.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000ffffffffff'
  }
} {1099511627775 57}
do_test boundary3-2.21.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=57
  }
} {1099511627775 000000ffffffffff}
do_test boundary3-2.21.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 1099511627775 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56}
do_test boundary3-2.21.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 1099511627775 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.21.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.21.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19}
do_test boundary3-2.21.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 1099511627775 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56 57}
do_test boundary3-2.21.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 1099511627775 ORDER BY t1.a DESC
  }
} {57 56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.21.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.21.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.21.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.21.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 1099511627775 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.21.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 1099511627775 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.21.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.21.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.21.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.21.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 1099511627775 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.21.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 1099511627775 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.21.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.21.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.21.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=57
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.21.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57}
do_test boundary3-2.21.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=57
     ORDER BY t1.rowid DESC
  }
} {57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-8388608 AND t2.a=t1.a
  }
} {37 ffffffffff800000}
do_test boundary3-2.22.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffff800000'
  }
} {-8388608 37}
do_test boundary3-2.22.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=37
  }
} {-8388608 ffffffffff800000}
do_test boundary3-2.22.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -8388608 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.22.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -8388608 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.22.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.22.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 29 32 54 53 52 33 38}
do_test boundary3-2.22.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29}
do_test boundary3-2.22.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -8388608 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.22.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -8388608 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.22.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.22.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 37 29 32 54 53 52 33 38}
do_test boundary3-2.22.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.22.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.22.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -8388608 ORDER BY t2.a
  }
} {1 2 11 21 44 47 55 58 63 64}
do_test boundary3-2.22.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -8388608 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2 1}
do_test boundary3-2.22.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.22.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.22.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.22.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -8388608 ORDER BY t2.a
  }
} {1 2 11 21 37 44 47 55 58 63 64}
do_test boundary3-2.22.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -8388608 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 21 11 2 1}
do_test boundary3-2.22.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.22.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.22.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=37
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.22.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37}
do_test boundary3-2.22.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=37
     ORDER BY t1.rowid DESC
  }
} {37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=549755813888 AND t2.a=t1.a
  }
} {35 0000008000000000}
do_test boundary3-2.23.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000008000000000'
  }
} {549755813888 35}
do_test boundary3-2.23.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=35
  }
} {549755813888 0000008000000000}
do_test boundary3-2.23.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 549755813888 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 43 45 56 57}
do_test boundary3-2.23.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 549755813888 ORDER BY t1.a DESC
  }
} {57 56 45 43 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.23.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.23.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57}
do_test boundary3-2.23.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 549755813888 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 56 57}
do_test boundary3-2.23.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 549755813888 ORDER BY t1.a DESC
  }
} {57 56 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.23.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.23.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.23.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.23.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 549755813888 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.23.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 549755813888 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.23.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.23.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.23.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.23.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 549755813888 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.23.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 549755813888 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.23.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.23.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.23.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=35
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.23.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35}
do_test boundary3-2.23.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=35
     ORDER BY t1.rowid DESC
  }
} {35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=8388607 AND t2.a=t1.a
  }
} {18 00000000007fffff}
do_test boundary3-2.24.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000007fffff'
  }
} {8388607 18}
do_test boundary3-2.24.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=18
  }
} {8388607 00000000007fffff}
do_test boundary3-2.24.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 8388607 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.24.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 8388607 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.24.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.24.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.24.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 8388607 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.24.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 8388607 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.24.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.24.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.24.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.24.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 8388607 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.24.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 8388607 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.24.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.24.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.24.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.24.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 8388607 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.24.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 8388607 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.24.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.24.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.24.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=18
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.24.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.24.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=18
     ORDER BY t1.rowid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-3 AND t2.a=t1.a
  }
} {52 fffffffffffffffd}
do_test boundary3-2.25.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='fffffffffffffffd'
  }
} {-3 52}
do_test boundary3-2.25.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=52
  }
} {-3 fffffffffffffffd}
do_test boundary3-2.25.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -3 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.25.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -3 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.25.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.25.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 33 38}
do_test boundary3-2.25.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.25.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -3 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 56 57 59 60 61 62}
do_test boundary3-2.25.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -3 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.25.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.25.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 52 33 38}
do_test boundary3-2.25.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.25.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.25.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -3 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 53 54 55 58 63 64}
do_test boundary3-2.25.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -3 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.25.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.25.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.25.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.25.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -3 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.25.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -3 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.25.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.25.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.25.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=52
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.25.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.25.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=52
     ORDER BY t1.rowid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=0 AND t2.a=t1.a
  }
} {59 0000000000000000}
do_test boundary3-2.26.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000000'
  }
} {0 59}
do_test boundary3-2.26.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=59
  }
} {0 0000000000000000}
do_test boundary3-2.26.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 0 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 60 61 62}
do_test boundary3-2.26.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 0 ORDER BY t1.a DESC
  }
} {62 61 60 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.26.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.26.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.26.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 0 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.26.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 0 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.26.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.26.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.26.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.26.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 0 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.26.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 0 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.26.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 0 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 63 64}
do_test boundary3-2.26.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 0 ORDER BY t1.a DESC
  }
} {64 63 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.26.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.26.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.26.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=59
     ORDER BY x
  }
} {59 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.26.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.26.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=59
     ORDER BY t1.rowid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-1 AND t2.a=t1.a
  }
} {38 ffffffffffffffff}
do_test boundary3-2.27.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffffffff'
  }
} {-1 38}
do_test boundary3-2.27.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=38
  }
} {-1 ffffffffffffffff}
do_test boundary3-2.27.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.27.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -1 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.27.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.27.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59}
do_test boundary3-2.27.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.27.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -1 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.27.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.27.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 38}
do_test boundary3-2.27.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.27.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.27.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.27.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -1 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 33 32 29 21 11 2 1}
do_test boundary3-2.27.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.27.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.27.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.27.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.27.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -1 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.27.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.27.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.27.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=38
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.27.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.27.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=38
     ORDER BY t1.rowid DESC
  }
} {38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-2 AND t2.a=t1.a
  }
} {33 fffffffffffffffe}
do_test boundary3-2.28.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='fffffffffffffffe'
  }
} {-2 33}
do_test boundary3-2.28.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=33
  }
} {-2 fffffffffffffffe}
do_test boundary3-2.28.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.28.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -2 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.28.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.28.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 38}
do_test boundary3-2.28.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38}
do_test boundary3-2.28.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -2 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 56 57 59 60 61 62}
do_test boundary3-2.28.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -2 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.28.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.28.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 33 38}
do_test boundary3-2.28.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.28.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33}
do_test boundary3-2.28.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.28.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -2 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.28.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.28.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.28.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52}
do_test boundary3-2.28.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -2 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 44 47 52 53 54 55 58 63 64}
do_test boundary3-2.28.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -2 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 52 47 44 37 33 32 29 21 11 2 1}
do_test boundary3-2.28.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.28.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.28.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=33
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.28.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33}
do_test boundary3-2.28.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=33
     ORDER BY t1.rowid DESC
  }
} {33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=2097152 AND t2.a=t1.a
  }
} {42 0000000000200000}
do_test boundary3-2.29.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000200000'
  }
} {2097152 42}
do_test boundary3-2.29.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=42
  }
} {2097152 0000000000200000}
do_test boundary3-2.29.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 2097152 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.29.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 2097152 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.29.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.29.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18}
do_test boundary3-2.29.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 2097152 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.29.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 2097152 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.29.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.29.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.29.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.29.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 2097152 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.29.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 2097152 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.29.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.29.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.29.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.29.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 2097152 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.29.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 2097152 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.29.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.29.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.29.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=42
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.29.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42}
do_test boundary3-2.29.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=42
     ORDER BY t1.rowid DESC
  }
} {42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=128 AND t2.a=t1.a
  }
} {49 0000000000000080}
do_test boundary3-2.30.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000080'
  }
} {128 49}
do_test boundary3-2.30.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=49
  }
} {128 0000000000000080}
do_test boundary3-2.30.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 128 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.30.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 128 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.30.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.30.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.30.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 128 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.30.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 128 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.30.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.30.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.30.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.30.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 128 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.30.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 128 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.30.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.30.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {59 60 41 5 31 4 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.30.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.30.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 128 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.30.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 128 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.30.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.30.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.30.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=49
     ORDER BY x
  }
} {59 60 41 5 31 4 49 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.30.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.30.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=49
     ORDER BY t1.rowid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=255 AND t2.a=t1.a
  }
} {30 00000000000000ff}
do_test boundary3-2.31.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000000000ff'
  }
} {255 30}
do_test boundary3-2.31.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=30
  }
} {255 00000000000000ff}
do_test boundary3-2.31.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 255 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.31.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 255 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.31.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.31.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61}
do_test boundary3-2.31.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 255 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 50 51 56 57 61 62}
do_test boundary3-2.31.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 255 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.31.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.31.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.31.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30}
do_test boundary3-2.31.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 255 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.31.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 255 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.31.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.31.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {59 60 41 5 31 4 49 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.31.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49}
do_test boundary3-2.31.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 255 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.31.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 255 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.31.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.31.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.31.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=30
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.31.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30}
do_test boundary3-2.31.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=30
     ORDER BY t1.rowid DESC
  }
} {30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.32.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-2147483648 AND t2.a=t1.a
  }
} {11 ffffffff80000000}
do_test boundary3-2.32.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffff80000000'
  }
} {-2147483648 11}
do_test boundary3-2.32.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=11
  }
} {-2147483648 ffffffff80000000}
do_test boundary3-2.32.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -2147483648 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.32.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -2147483648 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.32.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.32.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.32.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.32.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -2147483648 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.32.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -2147483648 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.32.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.32.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.32.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.32.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.32.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -2147483648 ORDER BY t2.a
  }
} {2 21 44 47 55 58 63 64}
do_test boundary3-2.32.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -2147483648 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 2}
do_test boundary3-2.32.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.32.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.32.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.32.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.32.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.32.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -2147483648 ORDER BY t2.a
  }
} {2 11 21 44 47 55 58 63 64}
do_test boundary3-2.32.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -2147483648 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2}
do_test boundary3-2.32.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.32.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.32.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=11
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.32.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.32.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=11
     ORDER BY t1.rowid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=34359738367 AND t2.a=t1.a
  }
} {39 00000007ffffffff}
do_test boundary3-2.33.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000007ffffffff'
  }
} {34359738367 39}
do_test boundary3-2.33.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=39
  }
} {34359738367 00000007ffffffff}
do_test boundary3-2.33.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 34359738367 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.33.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 34359738367 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.33.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.33.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22}
do_test boundary3-2.33.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 34359738367 ORDER BY t2.a
  }
} {3 7 10 13 17 19 22 25 26 27 28 34 35 39 43 45 46 56 57}
do_test boundary3-2.33.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 34359738367 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 35 34 28 27 26 25 22 19 17 13 10 7 3}
do_test boundary3-2.33.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.33.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.33.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39}
do_test boundary3-2.33.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 34359738367 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.33.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 34359738367 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.33.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.33.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.33.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36}
do_test boundary3-2.33.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 34359738367 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.33.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 34359738367 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.33.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.33.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.33.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=39
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.33.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39}
do_test boundary3-2.33.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=39
     ORDER BY t1.rowid DESC
  }
} {39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.34.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-549755813889 AND t2.a=t1.a
  }
} {58 ffffff7fffffffff}
do_test boundary3-2.34.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffff7fffffffff'
  }
} {-549755813889 58}
do_test boundary3-2.34.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=58
  }
} {-549755813889 ffffff7fffffffff}
do_test boundary3-2.34.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -549755813889 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62 63}
do_test boundary3-2.34.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -549755813889 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.34.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.34.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.34.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.34.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -549755813889 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 58 59 60 61 62 63}
do_test boundary3-2.34.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -549755813889 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.34.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58}
do_test boundary3-2.34.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.34.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.34.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58}
do_test boundary3-2.34.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -549755813889 ORDER BY t2.a
  }
} {2 21 44 55 64}
do_test boundary3-2.34.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -549755813889 ORDER BY t1.a DESC
  }
} {64 55 44 21 2}
do_test boundary3-2.34.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {55 2 64 21 44}
do_test boundary3-2.34.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {44 21 64 2 55}
do_test boundary3-2.34.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {55 2 64 21 44}
do_test boundary3-2.34.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {55 2 64 21 44}
do_test boundary3-2.34.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {44 21 64 2 55}
do_test boundary3-2.34.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -549755813889 ORDER BY t2.a
  }
} {2 21 44 55 58 64}
do_test boundary3-2.34.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -549755813889 ORDER BY t1.a DESC
  }
} {64 58 55 44 21 2}
do_test boundary3-2.34.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.34.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.34.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=58
     ORDER BY x
  }
} {55 2 64 21 44 58}
do_test boundary3-2.34.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.34.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=58
     ORDER BY t1.rowid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.35.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-32768 AND t2.a=t1.a
  }
} {32 ffffffffffff8000}
do_test boundary3-2.35.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffff8000'
  }
} {-32768 32}
do_test boundary3-2.35.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=32
  }
} {-32768 ffffffffffff8000}
do_test boundary3-2.35.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -32768 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.35.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -32768 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.35.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.35.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 54 53 52 33 38}
do_test boundary3-2.35.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.35.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -32768 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 32 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.35.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -32768 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 32 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.35.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.35.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 32 54 53 52 33 38}
do_test boundary3-2.35.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.35.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32}
do_test boundary3-2.35.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -32768 ORDER BY t2.a
  }
} {1 2 11 21 29 37 44 47 55 58 63 64}
do_test boundary3-2.35.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -32768 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 29 21 11 2 1}
do_test boundary3-2.35.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.35.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.35.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.35.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29}
do_test boundary3-2.35.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.35.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -32768 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 55 58 63 64}
do_test boundary3-2.35.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -32768 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.35.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.35.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.35.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=32
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.35.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.35.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=32
     ORDER BY t1.rowid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=2147483647 AND t2.a=t1.a
  }
} {20 000000007fffffff}
do_test boundary3-2.36.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000007fffffff'
  }
} {2147483647 20}
do_test boundary3-2.36.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=20
  }
} {2147483647 000000007fffffff}
do_test boundary3-2.36.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 2147483647 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.36.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 2147483647 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.36.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.36.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.36.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 2147483647 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.36.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 2147483647 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.36.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.36.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.36.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20}
do_test boundary3-2.36.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 2147483647 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.36.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 2147483647 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.36.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.36.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.36.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40}
do_test boundary3-2.36.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 2147483647 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.36.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 2147483647 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.36.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.36.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.36.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=20
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.36.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.36.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=20
     ORDER BY t1.rowid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-129 AND t2.a=t1.a
  }
} {54 ffffffffffffff7f}
do_test boundary3-2.37.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffffff7f'
  }
} {-129 54}
do_test boundary3-2.37.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=54
  }
} {-129 ffffffffffffff7f}
do_test boundary3-2.37.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -129 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 56 57 59 60 61 62}
do_test boundary3-2.37.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -129 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.37.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.37.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 53 52 33 38}
do_test boundary3-2.37.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.37.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -129 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.37.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -129 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.37.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.37.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 54 53 52 33 38}
do_test boundary3-2.37.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.37.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54}
do_test boundary3-2.37.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -129 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 55 58 63 64}
do_test boundary3-2.37.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -129 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.37.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.37.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.37.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32}
do_test boundary3-2.37.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -129 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 54 55 58 63 64}
do_test boundary3-2.37.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -129 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.37.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.37.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.37.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=54
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.37.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.37.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=54
     ORDER BY t1.rowid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-128 AND t2.a=t1.a
  }
} {53 ffffffffffffff80}
do_test boundary3-2.38.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffffffff80'
  }
} {-128 53}
do_test boundary3-2.38.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=53
  }
} {-128 ffffffffffffff80}
do_test boundary3-2.38.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -128 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 56 57 59 60 61 62}
do_test boundary3-2.38.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -128 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.38.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.38.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 52 33 38}
do_test boundary3-2.38.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52}
do_test boundary3-2.38.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -128 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 33 34 35 36 38 39 40 41 42 43 45 46 48 49 50 51 52 53 56 57 59 60 61 62}
do_test boundary3-2.38.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -128 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 53 52 51 50 49 48 46 45 43 42 41 40 39 38 36 35 34 33 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.38.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.38.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 53 52 33 38}
do_test boundary3-2.38.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.38.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53}
do_test boundary3-2.38.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -128 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 54 55 58 63 64}
do_test boundary3-2.38.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -128 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.38.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.38.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.38.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54}
do_test boundary3-2.38.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -128 ORDER BY t2.a
  }
} {1 2 11 21 29 32 37 44 47 53 54 55 58 63 64}
do_test boundary3-2.38.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -128 ORDER BY t1.a DESC
  }
} {64 63 58 55 54 53 47 44 37 32 29 21 11 2 1}
do_test boundary3-2.38.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.38.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.38.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=53
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.38.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53}
do_test boundary3-2.38.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=53
     ORDER BY t1.rowid DESC
  }
} {53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.39.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=72057594037927936 AND t2.a=t1.a
  }
} {28 0100000000000000}
do_test boundary3-2.39.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0100000000000000'
  }
} {72057594037927936 28}
do_test boundary3-2.39.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=28
  }
} {72057594037927936 0100000000000000}
do_test boundary3-2.39.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 72057594037927936 ORDER BY t2.a
  }
} {3}
do_test boundary3-2.39.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 72057594037927936 ORDER BY t1.a DESC
  }
} {3}
do_test boundary3-2.39.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid
  }
} {3}
do_test boundary3-2.39.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid DESC
  }
} {3}
do_test boundary3-2.39.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {3}
do_test boundary3-2.39.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 72057594037927936 ORDER BY t2.a
  }
} {3 28}
do_test boundary3-2.39.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 72057594037927936 ORDER BY t1.a DESC
  }
} {28 3}
do_test boundary3-2.39.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid
  }
} {28 3}
do_test boundary3-2.39.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid DESC
  }
} {3 28}
do_test boundary3-2.39.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {28 3}
do_test boundary3-2.39.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 72057594037927936 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.39.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 72057594037927936 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.39.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17}
do_test boundary3-2.39.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid DESC
  }
} {17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.39.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.39.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 72057594037927936 ORDER BY t2.a
  }
} {1 2 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}
do_test boundary3-2.39.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 72057594037927936 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.39.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28}
do_test boundary3-2.39.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=28
     ORDER BY t1.rowid DESC
  }
} {28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.39.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=28
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.40.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=2147483648 AND t2.a=t1.a
  }
} {51 0000000080000000}
do_test boundary3-2.40.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000080000000'
  }
} {2147483648 51}
do_test boundary3-2.40.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=51
  }
} {2147483648 0000000080000000}
do_test boundary3-2.40.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 2147483648 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 56 57}
do_test boundary3-2.40.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 2147483648 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.40.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.40.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14}
do_test boundary3-2.40.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 2147483648 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 22 25 26 27 28 34 35 36 39 43 45 46 51 56 57}
do_test boundary3-2.40.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 2147483648 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 39 36 35 34 28 27 26 25 22 19 17 14 13 10 7 3}
do_test boundary3-2.40.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.40.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.40.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51}
do_test boundary3-2.40.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 2147483648 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.40.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 2147483648 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.40.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.40.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.40.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.40.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20}
do_test boundary3-2.40.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.40.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 2147483648 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 20 21 23 24 29 30 31 32 33 37 38 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.40.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 2147483648 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 38 37 33 32 31 30 29 24 23 21 20 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.40.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.40.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.40.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=51
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.40.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51}
do_test boundary3-2.40.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=51
     ORDER BY t1.rowid DESC
  }
} {51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=549755813887 AND t2.a=t1.a
  }
} {46 0000007fffffffff}
do_test boundary3-2.41.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000007fffffffff'
  }
} {549755813887 46}
do_test boundary3-2.41.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=46
  }
} {549755813887 0000007fffffffff}
do_test boundary3-2.41.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 549755813887 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 56 57}
do_test boundary3-2.41.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 549755813887 ORDER BY t1.a DESC
  }
} {57 56 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.41.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.41.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35}
do_test boundary3-2.41.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 549755813887 ORDER BY t2.a
  }
} {3 7 10 13 17 19 25 26 27 28 34 35 43 45 46 56 57}
do_test boundary3-2.41.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 549755813887 ORDER BY t1.a DESC
  }
} {57 56 46 45 43 35 34 28 27 26 25 19 17 13 10 7 3}
do_test boundary3-2.41.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.41.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.41.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46}
do_test boundary3-2.41.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 549755813887 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.41.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 549755813887 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.41.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.41.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.41.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22}
do_test boundary3-2.41.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 549755813887 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 20 21 22 23 24 29 30 31 32 33 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.41.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 549755813887 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 33 32 31 30 29 24 23 22 21 20 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.41.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.41.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.41.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=46
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.41.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46}
do_test boundary3-2.41.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=46
     ORDER BY t1.rowid DESC
  }
} {46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.42.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-549755813888 AND t2.a=t1.a
  }
} {63 ffffff8000000000}
do_test boundary3-2.42.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffff8000000000'
  }
} {-549755813888 63}
do_test boundary3-2.42.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=63
  }
} {-549755813888 ffffff8000000000}
do_test boundary3-2.42.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -549755813888 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.42.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -549755813888 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.42.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.42.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.42.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.42.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -549755813888 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62 63}
do_test boundary3-2.42.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -549755813888 ORDER BY t1.a DESC
  }
} {63 62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.42.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.42.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.42.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.42.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63}
do_test boundary3-2.42.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -549755813888 ORDER BY t2.a
  }
} {2 21 44 55 58 64}
do_test boundary3-2.42.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -549755813888 ORDER BY t1.a DESC
  }
} {64 58 55 44 21 2}
do_test boundary3-2.42.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.42.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.42.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {55 2 64 21 44 58}
do_test boundary3-2.42.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58}
do_test boundary3-2.42.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {58 44 21 64 2 55}
do_test boundary3-2.42.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -549755813888 ORDER BY t2.a
  }
} {2 21 44 55 58 63 64}
do_test boundary3-2.42.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -549755813888 ORDER BY t1.a DESC
  }
} {64 63 58 55 44 21 2}
do_test boundary3-2.42.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.42.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.42.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=63
     ORDER BY x
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.42.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.42.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=63
     ORDER BY t1.rowid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.43.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=281474976710655 AND t2.a=t1.a
  }
} {10 0000ffffffffffff}
do_test boundary3-2.43.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000ffffffffffff'
  }
} {281474976710655 10}
do_test boundary3-2.43.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=10
  }
} {281474976710655 0000ffffffffffff}
do_test boundary3-2.43.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 281474976710655 ORDER BY t2.a
  }
} {3 13 17 26 27 28 43 45}
do_test boundary3-2.43.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 281474976710655 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 3}
do_test boundary3-2.43.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.43.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26}
do_test boundary3-2.43.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.43.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 281474976710655 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 43 45}
do_test boundary3-2.43.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 281474976710655 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 10 3}
do_test boundary3-2.43.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.43.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10}
do_test boundary3-2.43.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.43.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 281474976710655 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.43.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 281474976710655 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.43.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34}
do_test boundary3-2.43.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid DESC
  }
} {34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.43.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.43.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 281474976710655 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.43.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 281474976710655 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.43.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10}
do_test boundary3-2.43.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=10
     ORDER BY t1.rowid DESC
  }
} {10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.43.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=10
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.44.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=4398046511103 AND t2.a=t1.a
  }
} {7 000003ffffffffff}
do_test boundary3-2.44.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000003ffffffffff'
  }
} {4398046511103 7}
do_test boundary3-2.44.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=7
  }
} {4398046511103 000003ffffffffff}
do_test boundary3-2.44.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 4398046511103 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.44.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 4398046511103 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.44.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.44.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.44.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 4398046511103 ORDER BY t2.a
  }
} {3 7 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.44.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 4398046511103 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 7 3}
do_test boundary3-2.44.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.44.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.44.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7}
do_test boundary3-2.44.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 4398046511103 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.44.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 4398046511103 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.44.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.44.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.44.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.44.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19}
do_test boundary3-2.44.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.44.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 4398046511103 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.44.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 4398046511103 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.44.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.44.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.44.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=7
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.44.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.44.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=7
     ORDER BY t1.rowid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=268435455 AND t2.a=t1.a
  }
} {12 000000000fffffff}
do_test boundary3-2.45.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000000fffffff'
  }
} {268435455 12}
do_test boundary3-2.45.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=12
  }
} {268435455 000000000fffffff}
do_test boundary3-2.45.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 268435455 ORDER BY t2.a
  }
} {3 7 10 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.45.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 268435455 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 10 7 3}
do_test boundary3-2.45.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.45.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40}
do_test boundary3-2.45.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 268435455 ORDER BY t2.a
  }
} {3 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.45.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 268435455 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 3}
do_test boundary3-2.45.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.45.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.45.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12}
do_test boundary3-2.45.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 268435455 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.45.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 268435455 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 6 5 4 2 1}
do_test boundary3-2.45.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.45.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.45.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6}
do_test boundary3-2.45.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 268435455 ORDER BY t2.a
  }
} {1 2 4 5 6 8 9 11 12 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.45.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 268435455 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 12 11 9 8 6 5 4 2 1}
do_test boundary3-2.45.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.45.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.45.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=12
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.45.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12}
do_test boundary3-2.45.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=12
     ORDER BY t1.rowid DESC
  }
} {12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.46.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-9223372036854775808 AND t2.a=t1.a
  }
} {55 8000000000000000}
do_test boundary3-2.46.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='8000000000000000'
  }
} {-9223372036854775808 55}
do_test boundary3-2.46.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=55
  }
} {-9223372036854775808 8000000000000000}
do_test boundary3-2.46.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -9223372036854775808 ORDER BY t2.a
  }
} {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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.46.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -9223372036854775808 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.46.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid
  }
} {2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.46.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2}
do_test boundary3-2.46.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.46.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -9223372036854775808 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.46.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -9223372036854775808 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.46.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.46.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.46.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.46.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -9223372036854775808 ORDER BY t2.a
  }
} {}
do_test boundary3-2.46.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -9223372036854775808 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.46.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid
  }
} {}
do_test boundary3-2.46.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid DESC
  }
} {}
do_test boundary3-2.46.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {}
do_test boundary3-2.46.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -9223372036854775808 ORDER BY t2.a
  }
} {55}
do_test boundary3-2.46.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -9223372036854775808 ORDER BY t1.a DESC
  }
} {55}
do_test boundary3-2.46.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid
  }
} {55}
do_test boundary3-2.46.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=55
     ORDER BY t1.rowid DESC
  }
} {55}
do_test boundary3-2.46.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=55
     ORDER BY x
  }
} {55}
do_test boundary3-2.47.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=562949953421312 AND t2.a=t1.a
  }
} {43 0002000000000000}
do_test boundary3-2.47.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0002000000000000'
  }
} {562949953421312 43}
do_test boundary3-2.47.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=43
  }
} {562949953421312 0002000000000000}
do_test boundary3-2.47.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 562949953421312 ORDER BY t2.a
  }
} {3 17 27 28 45}
do_test boundary3-2.47.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 562949953421312 ORDER BY t1.a DESC
  }
} {45 28 27 17 3}
do_test boundary3-2.47.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid
  }
} {27 45 17 28 3}
do_test boundary3-2.47.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27}
do_test boundary3-2.47.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {27 45 17 28 3}
do_test boundary3-2.47.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 562949953421312 ORDER BY t2.a
  }
} {3 17 27 28 43 45}
do_test boundary3-2.47.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 562949953421312 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 3}
do_test boundary3-2.47.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid
  }
} {43 27 45 17 28 3}
do_test boundary3-2.47.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43}
do_test boundary3-2.47.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {43 27 45 17 28 3}
do_test boundary3-2.47.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 562949953421312 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.47.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 562949953421312 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.47.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13}
do_test boundary3-2.47.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid DESC
  }
} {13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.47.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.47.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 562949953421312 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.47.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 562949953421312 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.47.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43}
do_test boundary3-2.47.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=43
     ORDER BY t1.rowid DESC
  }
} {43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.47.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=43
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.48.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-8388609 AND t2.a=t1.a
  }
} {1 ffffffffff7fffff}
do_test boundary3-2.48.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffffff7fffff'
  }
} {-8388609 1}
do_test boundary3-2.48.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=1
  }
} {-8388609 ffffffffff7fffff}
do_test boundary3-2.48.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -8388609 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.48.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -8388609 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.48.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.48.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 37 29 32 54 53 52 33 38}
do_test boundary3-2.48.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37}
do_test boundary3-2.48.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -8388609 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.48.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -8388609 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.48.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.48.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.48.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.48.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1}
do_test boundary3-2.48.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -8388609 ORDER BY t2.a
  }
} {2 11 21 44 47 55 58 63 64}
do_test boundary3-2.48.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -8388609 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2}
do_test boundary3-2.48.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.48.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.48.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.48.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11}
do_test boundary3-2.48.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {11 47 63 58 44 21 64 2 55}
do_test boundary3-2.48.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -8388609 ORDER BY t2.a
  }
} {1 2 11 21 44 47 55 58 63 64}
do_test boundary3-2.48.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -8388609 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 11 2 1}
do_test boundary3-2.48.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.48.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.48.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=1
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.48.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1}
do_test boundary3-2.48.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=1
     ORDER BY t1.rowid DESC
  }
} {1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=16777215 AND t2.a=t1.a
  }
} {9 0000000000ffffff}
do_test boundary3-2.49.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000ffffff'
  }
} {16777215 9}
do_test boundary3-2.49.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=9
  }
} {16777215 0000000000ffffff}
do_test boundary3-2.49.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 16777215 ORDER BY t2.a
  }
} {3 6 7 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.49.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 16777215 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 7 6 3}
do_test boundary3-2.49.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.49.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6}
do_test boundary3-2.49.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 16777215 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.49.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 16777215 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.49.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.49.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.49.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.49.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 16777215 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.49.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 16777215 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.49.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.49.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.49.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.49.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 16777215 ORDER BY t2.a
  }
} {1 2 4 5 8 9 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.49.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 16777215 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 9 8 5 4 2 1}
do_test boundary3-2.49.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.49.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.49.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=9
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.49.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9}
do_test boundary3-2.49.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=9
     ORDER BY t1.rowid DESC
  }
} {9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=8388608 AND t2.a=t1.a
  }
} {24 0000000000800000}
do_test boundary3-2.50.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000800000'
  }
} {8388608 24}
do_test boundary3-2.50.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=24
  }
} {8388608 0000000000800000}
do_test boundary3-2.50.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 8388608 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.50.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 8388608 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.50.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.50.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9}
do_test boundary3-2.50.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 8388608 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 19 20 22 24 25 26 27 28 34 35 36 39 40 43 45 46 51 56 57}
do_test boundary3-2.50.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 8388608 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 40 39 36 35 34 28 27 26 25 24 22 20 19 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.50.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.50.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.50.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24}
do_test boundary3-2.50.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 8388608 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.50.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 8388608 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.50.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.50.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.50.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18}
do_test boundary3-2.50.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 8388608 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 18 21 23 24 29 30 31 32 33 37 38 41 42 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.50.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 8388608 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 42 41 38 37 33 32 31 30 29 24 23 21 18 16 15 11 8 5 4 2 1}
do_test boundary3-2.50.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.50.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.50.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=24
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.50.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24}
do_test boundary3-2.50.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=24
     ORDER BY t1.rowid DESC
  }
} {24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=16383 AND t2.a=t1.a
  }
} {8 0000000000003fff}
do_test boundary3-2.51.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000003fff'
  }
} {16383 8}
do_test boundary3-2.51.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=8
  }
} {16383 0000000000003fff}
do_test boundary3-2.51.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 16383 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.51.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 16383 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.51.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.51.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16}
do_test boundary3-2.51.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 16383 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.51.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 16383 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.51.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.51.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.51.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8}
do_test boundary3-2.51.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 16383 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.51.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 16383 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 5 4 2 1}
do_test boundary3-2.51.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.51.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.51.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61}
do_test boundary3-2.51.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 16383 ORDER BY t2.a
  }
} {1 2 4 5 8 11 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.51.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 16383 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 11 8 5 4 2 1}
do_test boundary3-2.51.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.51.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.51.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=8
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.51.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8}
do_test boundary3-2.51.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=8
     ORDER BY t1.rowid DESC
  }
} {8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.52.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=140737488355328 AND t2.a=t1.a
  }
} {34 0000800000000000}
do_test boundary3-2.52.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000800000000000'
  }
} {140737488355328 34}
do_test boundary3-2.52.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=34
  }
} {140737488355328 0000800000000000}
do_test boundary3-2.52.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 140737488355328 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 43 45}
do_test boundary3-2.52.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 140737488355328 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 10 3}
do_test boundary3-2.52.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10}
do_test boundary3-2.52.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 140737488355328 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 34 43 45}
do_test boundary3-2.52.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 140737488355328 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 17 13 10 3}
do_test boundary3-2.52.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34}
do_test boundary3-2.52.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.52.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 140737488355328 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.52.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 140737488355328 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.52.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25}
do_test boundary3-2.52.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid DESC
  }
} {25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.52.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.52.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 140737488355328 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.52.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 140737488355328 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.52.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34}
do_test boundary3-2.52.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=34
     ORDER BY t1.rowid DESC
  }
} {34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.52.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=34
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.53.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=2097151 AND t2.a=t1.a
  }
} {15 00000000001fffff}
do_test boundary3-2.53.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00000000001fffff'
  }
} {2097151 15}
do_test boundary3-2.53.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=15
  }
} {2097151 00000000001fffff}
do_test boundary3-2.53.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 2097151 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.53.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 2097151 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 14 13 12 10 9 7 6 3}
do_test boundary3-2.53.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.53.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42}
do_test boundary3-2.53.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 2097151 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 51 56 57}
do_test boundary3-2.53.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 2097151 ORDER BY t1.a DESC
  }
} {57 56 51 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.53.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.53.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.53.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15}
do_test boundary3-2.53.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 2097151 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.53.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 2097151 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.53.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.53.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.53.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.53.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62}
do_test boundary3-2.53.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.53.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 2097151 ORDER BY t2.a
  }
} {1 2 4 5 8 11 15 16 21 23 29 30 31 32 33 37 38 41 44 47 48 49 50 52 53 54 55 58 59 60 61 62 63 64}
do_test boundary3-2.53.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 2097151 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 55 54 53 52 50 49 48 47 44 41 38 37 33 32 31 30 29 23 21 16 15 11 8 5 4 2 1}
do_test boundary3-2.53.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.53.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.53.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=15
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.53.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15}
do_test boundary3-2.53.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=15
     ORDER BY t1.rowid DESC
  }
} {15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.54.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=140737488355327 AND t2.a=t1.a
  }
} {25 00007fffffffffff}
do_test boundary3-2.54.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='00007fffffffffff'
  }
} {140737488355327 25}
do_test boundary3-2.54.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=25
  }
} {140737488355327 00007fffffffffff}
do_test boundary3-2.54.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 140737488355327 ORDER BY t2.a
  }
} {3 10 13 17 26 27 28 34 43 45}
do_test boundary3-2.54.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 140737488355327 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 17 13 10 3}
do_test boundary3-2.54.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34}
do_test boundary3-2.54.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 140737488355327 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45}
do_test boundary3-2.54.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 140737488355327 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.54.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25}
do_test boundary3-2.54.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.54.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 140737488355327 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.54.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 140737488355327 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.54.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56}
do_test boundary3-2.54.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid DESC
  }
} {56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.54.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.54.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 140737488355327 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.54.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 140737488355327 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.54.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25}
do_test boundary3-2.54.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=25
     ORDER BY t1.rowid DESC
  }
} {25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.54.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=25
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.55.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=281474976710656 AND t2.a=t1.a
  }
} {26 0001000000000000}
do_test boundary3-2.55.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0001000000000000'
  }
} {281474976710656 26}
do_test boundary3-2.55.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=26
  }
} {281474976710656 0001000000000000}
do_test boundary3-2.55.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 281474976710656 ORDER BY t2.a
  }
} {3 13 17 27 28 43 45}
do_test boundary3-2.55.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 281474976710656 ORDER BY t1.a DESC
  }
} {45 43 28 27 17 13 3}
do_test boundary3-2.55.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.55.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13}
do_test boundary3-2.55.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {13 43 27 45 17 28 3}
do_test boundary3-2.55.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 281474976710656 ORDER BY t2.a
  }
} {3 13 17 26 27 28 43 45}
do_test boundary3-2.55.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 281474976710656 ORDER BY t1.a DESC
  }
} {45 43 28 27 26 17 13 3}
do_test boundary3-2.55.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.55.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26}
do_test boundary3-2.55.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {26 13 43 27 45 17 28 3}
do_test boundary3-2.55.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 281474976710656 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.55.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 281474976710656 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.55.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10}
do_test boundary3-2.55.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid DESC
  }
} {10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.55.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.55.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 281474976710656 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.55.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 281474976710656 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.55.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26}
do_test boundary3-2.55.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=26
     ORDER BY t1.rowid DESC
  }
} {26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.55.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=26
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.56.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=32767 AND t2.a=t1.a
  }
} {23 0000000000007fff}
do_test boundary3-2.56.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000007fff'
  }
} {32767 23}
do_test boundary3-2.56.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=23
  }
} {32767 0000000000007fff}
do_test boundary3-2.56.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 32767 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.56.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 32767 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.56.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.56.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50}
do_test boundary3-2.56.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 32767 ORDER BY t2.a
  }
} {3 6 7 9 10 12 13 14 15 17 18 19 20 22 23 24 25 26 27 28 34 35 36 39 40 42 43 45 46 48 50 51 56 57 62}
do_test boundary3-2.56.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 32767 ORDER BY t1.a DESC
  }
} {62 57 56 51 50 48 46 45 43 42 40 39 36 35 34 28 27 26 25 24 23 22 20 19 18 17 15 14 13 12 10 9 7 6 3}
do_test boundary3-2.56.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.56.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.56.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23}
do_test boundary3-2.56.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 32767 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.56.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 32767 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 21 16 11 8 5 4 2 1}
do_test boundary3-2.56.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.56.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.56.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.56.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16}
do_test boundary3-2.56.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.56.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 32767 ORDER BY t2.a
  }
} {1 2 4 5 8 11 16 21 23 29 30 31 32 33 37 38 41 44 47 49 52 53 54 55 58 59 60 61 63 64}
do_test boundary3-2.56.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 32767 ORDER BY t1.a DESC
  }
} {64 63 61 60 59 58 55 54 53 52 49 47 44 41 38 37 33 32 31 30 29 23 21 16 11 8 5 4 2 1}
do_test boundary3-2.56.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.56.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.56.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=23
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.56.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23}
do_test boundary3-2.56.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=23
     ORDER BY t1.rowid DESC
  }
} {23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=127 AND t2.a=t1.a
  }
} {4 000000000000007f}
do_test boundary3-2.57.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='000000000000007f'
  }
} {127 4}
do_test boundary3-2.57.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=4
  }
} {127 000000000000007f}
do_test boundary3-2.57.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 127 ORDER BY t2.a
  }
} {3 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.57.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 127 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 3}
do_test boundary3-2.57.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.57.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49}
do_test boundary3-2.57.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 127 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.57.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 127 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.57.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.57.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.57.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4}
do_test boundary3-2.57.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 127 ORDER BY t2.a
  }
} {1 2 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.57.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 127 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 2 1}
do_test boundary3-2.57.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.57.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {59 60 41 5 31 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.57.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31}
do_test boundary3-2.57.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 127 ORDER BY t2.a
  }
} {1 2 4 5 11 21 29 31 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.57.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 127 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 31 29 21 11 5 4 2 1}
do_test boundary3-2.57.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.57.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.57.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=4
     ORDER BY x
  }
} {59 60 41 5 31 4 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.57.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4}
do_test boundary3-2.57.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=4
     ORDER BY t1.rowid DESC
  }
} {4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.58.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=36028797018963967 AND t2.a=t1.a
  }
} {27 007fffffffffffff}
do_test boundary3-2.58.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='007fffffffffffff'
  }
} {36028797018963967 27}
do_test boundary3-2.58.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=27
  }
} {36028797018963967 007fffffffffffff}
do_test boundary3-2.58.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 36028797018963967 ORDER BY t2.a
  }
} {3 17 28 45}
do_test boundary3-2.58.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 36028797018963967 ORDER BY t1.a DESC
  }
} {45 28 17 3}
do_test boundary3-2.58.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid
  }
} {45 17 28 3}
do_test boundary3-2.58.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45}
do_test boundary3-2.58.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {45 17 28 3}
do_test boundary3-2.58.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 36028797018963967 ORDER BY t2.a
  }
} {3 17 27 28 45}
do_test boundary3-2.58.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 36028797018963967 ORDER BY t1.a DESC
  }
} {45 28 27 17 3}
do_test boundary3-2.58.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid
  }
} {27 45 17 28 3}
do_test boundary3-2.58.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27}
do_test boundary3-2.58.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {27 45 17 28 3}
do_test boundary3-2.58.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 36028797018963967 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.58.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 36028797018963967 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.58.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43}
do_test boundary3-2.58.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid DESC
  }
} {43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.58.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.58.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 36028797018963967 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.58.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 36028797018963967 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.58.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27}
do_test boundary3-2.58.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=27
     ORDER BY t1.rowid DESC
  }
} {27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.58.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=27
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.59.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=4398046511104 AND t2.a=t1.a
  }
} {56 0000040000000000}
do_test boundary3-2.59.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000040000000000'
  }
} {4398046511104 56}
do_test boundary3-2.59.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=56
  }
} {4398046511104 0000040000000000}
do_test boundary3-2.59.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 4398046511104 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45}
do_test boundary3-2.59.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 4398046511104 ORDER BY t1.a DESC
  }
} {45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.59.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25}
do_test boundary3-2.59.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25}
do_test boundary3-2.59.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 4398046511104 ORDER BY t2.a
  }
} {3 10 13 17 25 26 27 28 34 43 45 56}
do_test boundary3-2.59.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 4398046511104 ORDER BY t1.a DESC
  }
} {56 45 43 34 28 27 26 25 17 13 10 3}
do_test boundary3-2.59.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.59.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.59.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56}
do_test boundary3-2.59.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 4398046511104 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 57 58 59 60 61 62 63 64}
do_test boundary3-2.59.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 4398046511104 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.59.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.59.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.59.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.59.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7}
do_test boundary3-2.59.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.59.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 4398046511104 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 11 12 14 15 16 18 19 20 21 22 23 24 29 30 31 32 33 35 36 37 38 39 40 41 42 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.59.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 4398046511104 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 42 41 40 39 38 37 36 35 33 32 31 30 29 24 23 22 21 20 19 18 16 15 14 12 11 9 8 7 6 5 4 2 1}
do_test boundary3-2.59.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56}
do_test boundary3-2.59.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.59.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=56
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.59.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56}
do_test boundary3-2.59.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=56
     ORDER BY t1.rowid DESC
  }
} {56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=1 AND t2.a=t1.a
  }
} {60 0000000000000001}
do_test boundary3-2.60.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000001'
  }
} {1 60}
do_test boundary3-2.60.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=60
  }
} {1 0000000000000001}
do_test boundary3-2.60.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.60.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 1 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.60.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.60.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41}
do_test boundary3-2.60.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 1 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 41 42 43 45 46 48 49 50 51 56 57 60 61 62}
do_test boundary3-2.60.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 1 ORDER BY t1.a DESC
  }
} {62 61 60 57 56 51 50 49 48 46 45 43 42 41 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.60.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.60.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.60.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60}
do_test boundary3-2.60.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 63 64}
do_test boundary3-2.60.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 1 ORDER BY t1.a DESC
  }
} {64 63 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.60.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.60.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {59 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.60.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59}
do_test boundary3-2.60.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 1 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.60.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 1 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.60.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.60.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.60.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=60
     ORDER BY x
  }
} {59 60 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.60.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60}
do_test boundary3-2.60.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=60
     ORDER BY t1.rowid DESC
  }
} {60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.61.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=36028797018963968 AND t2.a=t1.a
  }
} {45 0080000000000000}
do_test boundary3-2.61.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0080000000000000'
  }
} {36028797018963968 45}
do_test boundary3-2.61.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=45
  }
} {36028797018963968 0080000000000000}
do_test boundary3-2.61.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 36028797018963968 ORDER BY t2.a
  }
} {3 17 28}
do_test boundary3-2.61.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 36028797018963968 ORDER BY t1.a DESC
  }
} {28 17 3}
do_test boundary3-2.61.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid
  }
} {17 28 3}
do_test boundary3-2.61.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid DESC
  }
} {3 28 17}
do_test boundary3-2.61.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {17 28 3}
do_test boundary3-2.61.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 36028797018963968 ORDER BY t2.a
  }
} {3 17 28 45}
do_test boundary3-2.61.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 36028797018963968 ORDER BY t1.a DESC
  }
} {45 28 17 3}
do_test boundary3-2.61.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid
  }
} {45 17 28 3}
do_test boundary3-2.61.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45}
do_test boundary3-2.61.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {45 17 28 3}
do_test boundary3-2.61.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 36028797018963968 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.61.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 36028797018963968 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.61.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27}
do_test boundary3-2.61.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid DESC
  }
} {27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.61.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.61.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 36028797018963968 ORDER BY t2.a
  }
} {1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 22 23 24 25 26 27 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}
do_test boundary3-2.61.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 36028797018963968 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 27 26 25 24 23 22 21 20 19 18 16 15 14 13 12 11 10 9 8 7 6 5 4 2 1}
do_test boundary3-2.61.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45}
do_test boundary3-2.61.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=45
     ORDER BY t1.rowid DESC
  }
} {45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.61.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=45
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.62.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-2147483649 AND t2.a=t1.a
  }
} {47 ffffffff7fffffff}
do_test boundary3-2.62.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ffffffff7fffffff'
  }
} {-2147483649 47}
do_test boundary3-2.62.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=47
  }
} {-2147483649 ffffffff7fffffff}
do_test boundary3-2.62.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -2147483649 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.62.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -2147483649 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.62.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.62.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.62.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11}
do_test boundary3-2.62.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -2147483649 ORDER BY t2.a
  }
} {1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57 59 60 61 62}
do_test boundary3-2.62.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -2147483649 ORDER BY t1.a DESC
  }
} {62 61 60 59 57 56 54 53 52 51 50 49 48 47 46 45 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.62.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.62.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.62.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.62.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47}
do_test boundary3-2.62.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -2147483649 ORDER BY t2.a
  }
} {2 21 44 55 58 63 64}
do_test boundary3-2.62.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -2147483649 ORDER BY t1.a DESC
  }
} {64 63 58 55 44 21 2}
do_test boundary3-2.62.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.62.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.62.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.62.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63}
do_test boundary3-2.62.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {63 58 44 21 64 2 55}
do_test boundary3-2.62.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -2147483649 ORDER BY t2.a
  }
} {2 21 44 47 55 58 63 64}
do_test boundary3-2.62.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -2147483649 ORDER BY t1.a DESC
  }
} {64 63 58 55 47 44 21 2}
do_test boundary3-2.62.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.62.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.62.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=47
     ORDER BY x
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.62.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47}
do_test boundary3-2.62.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=47
     ORDER BY t1.rowid DESC
  }
} {47 63 58 44 21 64 2 55}
do_test boundary3-2.63.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=-36028797018963969 AND t2.a=t1.a
  }
} {2 ff7fffffffffffff}
do_test boundary3-2.63.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='ff7fffffffffffff'
  }
} {-36028797018963969 2}
do_test boundary3-2.63.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=2
  }
} {-36028797018963969 ff7fffffffffffff}
do_test boundary3-2.63.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -36028797018963969 ORDER BY t2.a
  }
} {1 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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.63.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -36028797018963969 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1}
do_test boundary3-2.63.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid
  }
} {64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.63.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64}
do_test boundary3-2.63.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.63.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -36028797018963969 ORDER BY t2.a
  }
} {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 56 57 58 59 60 61 62 63 64}
do_test boundary3-2.63.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -36028797018963969 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.63.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid
  }
} {2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.63.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2}
do_test boundary3-2.63.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.63.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -36028797018963969 ORDER BY t2.a
  }
} {55}
do_test boundary3-2.63.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -36028797018963969 ORDER BY t1.a DESC
  }
} {55}
do_test boundary3-2.63.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid
  }
} {55}
do_test boundary3-2.63.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid DESC
  }
} {55}
do_test boundary3-2.63.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {55}
do_test boundary3-2.63.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -36028797018963969 ORDER BY t2.a
  }
} {2 55}
do_test boundary3-2.63.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -36028797018963969 ORDER BY t1.a DESC
  }
} {55 2}
do_test boundary3-2.63.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid
  }
} {55 2}
do_test boundary3-2.63.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=2
     ORDER BY t1.rowid DESC
  }
} {2 55}
do_test boundary3-2.63.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=2
     ORDER BY x
  }
} {55 2}
do_test boundary3-2.64.1 {
  db eval {
    SELECT t1.* FROM t1, t2 WHERE t1.rowid=3 AND t2.a=t1.a
  }
} {5 0000000000000003}
do_test boundary3-2.64.2 {
  db eval {
    SELECT t2.* FROM t1 JOIN t2 USING(a) WHERE x='0000000000000003'
  }
} {3 5}
do_test boundary3-2.64.3 {
  db eval {
    SELECT t1.rowid, x FROM t1 JOIN t2 ON t2.r=t1.rowid WHERE t2.a=5
  }
} {3 0000000000000003}
do_test boundary3-2.64.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 3 ORDER BY t2.a
  }
} {3 4 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.64.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 3 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 4 3}
do_test boundary3-2.64.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.64.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.gt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.gt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31}
do_test boundary3-2.64.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 3 ORDER BY t2.a
  }
} {3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 22 23 24 25 26 27 28 30 31 34 35 36 39 40 42 43 45 46 48 49 50 51 56 57 61 62}
do_test boundary3-2.64.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 3 ORDER BY t1.a DESC
  }
} {62 61 57 56 51 50 49 48 46 45 43 42 40 39 36 35 34 31 30 28 27 26 25 24 23 22 20 19 18 17 16 15 14 13 12 10 9 8 7 6 5 4 3}
do_test boundary3-2.64.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.64.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.ge.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.64.ge.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5}
do_test boundary3-2.64.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 3 ORDER BY t2.a
  }
} {1 2 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.64.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 3 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 2 1}
do_test boundary3-2.64.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.64.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.64.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {59 60 41 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.64.lt.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41}
do_test boundary3-2.64.lt.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.64.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 3 ORDER BY t2.a
  }
} {1 2 5 11 21 29 32 33 37 38 41 44 47 52 53 54 55 58 59 60 63 64}
do_test boundary3-2.64.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 3 ORDER BY t1.a DESC
  }
} {64 63 60 59 58 55 54 53 52 47 44 41 38 37 33 32 29 21 11 5 2 1}
do_test boundary3-2.64.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.64.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.64.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=5
     ORDER BY x
  }
} {59 60 41 5 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.64.le.10 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5}
do_test boundary3-2.64.le.11 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= CAST(t2.r AS real)
     WHERE t2.a=5
     ORDER BY t1.rowid DESC
  }
} {5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.65.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.65.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.65.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid
  }
} {}
do_test boundary3-2.65.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid DESC
  }
} {}
do_test boundary3-2.65.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {}
do_test boundary3-2.65.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.65.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.65.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid
  }
} {}
do_test boundary3-2.65.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid DESC
  }
} {}
do_test boundary3-2.65.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {}
do_test boundary3-2.65.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.65.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.65.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.65.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.65.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.65.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= 9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.65.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= 9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.65.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.65.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=65
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.65.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=65
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.66.gt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid > -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.66.gt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid > -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.66.gt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.66.gt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.66.gt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid > t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.66.ge.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid >= -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {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}
do_test boundary3-2.66.ge.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid >= -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_test boundary3-2.66.ge.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid
  }
} {55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38 59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3}
do_test boundary3-2.66.ge.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid DESC
  }
} {3 28 17 45 27 43 13 26 10 34 25 56 7 19 57 35 46 22 39 36 14 51 20 40 12 6 9 24 18 42 15 62 48 50 23 16 8 61 30 49 4 31 5 41 60 59 38 33 52 53 54 32 29 37 1 11 47 63 58 44 21 64 2 55}
do_test boundary3-2.66.ge.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid >= t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {59 60 41 5 31 4 49 30 61 8 16 23 50 48 62 15 42 18 24 9 6 12 40 20 51 14 36 39 22 46 35 57 19 7 56 25 34 10 26 13 43 27 45 17 28 3 55 2 64 21 44 58 63 47 11 1 37 29 32 54 53 52 33 38}
do_test boundary3-2.66.lt.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid < -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.66.lt.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid < -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.66.lt.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid
  }
} {}
do_test boundary3-2.66.lt.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid DESC
  }
} {}
do_test boundary3-2.66.lt.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid < t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {}
do_test boundary3-2.66.le.1 {
  db eval {
    SELECT t2.a FROM t1 JOIN t2 USING(a)
     WHERE t1.rowid <= -9.22337303685477580800e+18 ORDER BY t2.a
  }
} {}
do_test boundary3-2.66.le.2 {
  db eval {
    SELECT t2.a FROM t2 NATURAL JOIN t1
     WHERE t1.rowid <= -9.22337303685477580800e+18 ORDER BY t1.a DESC
  }
} {}
do_test boundary3-2.66.le.3 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid
  }
} {}
do_test boundary3-2.66.le.4 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=66
     ORDER BY t1.rowid DESC
  }
} {}
do_test boundary3-2.66.le.5 {
  db eval {
    SELECT t1.a FROM t1 JOIN t2 ON t1.rowid <= t2.r
     WHERE t2.a=66
     ORDER BY x
  }
} {}
finish_test
Changes to test/capi2.test.
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#} {SQLITE4_MISUSE}
do_test capi2-3.13 {
  set VM [sqlite4_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite4_step $VM] \
       [sqlite4_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE4_CONSTRAINT 0 {} {}}

# Update for v3: Preparing a statement does not affect the change counter.
# (Test result changes from 0 to 1).  (Later:) change counter updates occur
# when sqlite4_step returns, not at finalize time.
do_test capi2-3.13b {db changes} {0}

do_test capi2-3.14 {







|







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#} {SQLITE4_MISUSE}
do_test capi2-3.13 {
  set VM [sqlite4_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite4_step $VM] \
       [sqlite4_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE4_ERROR 0 {} {}}

# Update for v3: Preparing a statement does not affect the change counter.
# (Test result changes from 0 to 1).  (Later:) change counter updates occur
# when sqlite4_step returns, not at finalize time.
do_test capi2-3.13b {db changes} {0}

do_test capi2-3.14 {
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
} {SQLITE4_OK {not an error}}
do_test capi2-3.18 {
  set VM [sqlite4_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL]
  list [sqlite4_step $VM] \
       [sqlite4_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE4_CONSTRAINT 0 {} {}}
do_test capi2-3.19 {
  list [sqlite4_finalize $VM] [sqlite4_errmsg $DB]
} {SQLITE4_CONSTRAINT {t2.a may not be NULL}}

do_test capi2-3.20 {
  execsql {
    CREATE TABLE a1(message_id, name , UNIQUE(message_id, name) );
    INSERT INTO a1 VALUES(1, 1);
  }
} {}
do_test capi2-3.21 {
  set VM [sqlite4_prepare $DB {INSERT INTO a1 VALUES(1, 1)} -1 TAIL]
  sqlite4_step $VM
} {SQLITE4_CONSTRAINT}
do_test capi2-3.22 {
  sqlite4_errcode $DB
} {SQLITE4_CONSTRAINT}
do_test capi2-3.23 {
  sqlite4_finalize $VM
} {SQLITE4_CONSTRAINT}
do_test capi2-3.24 {
  sqlite4_errcode $DB
} {SQLITE4_CONSTRAINT}








|













|


|







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
} {SQLITE4_OK {not an error}}
do_test capi2-3.18 {
  set VM [sqlite4_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL]
  list [sqlite4_step $VM] \
       [sqlite4_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE4_ERROR 0 {} {}}
do_test capi2-3.19 {
  list [sqlite4_finalize $VM] [sqlite4_errmsg $DB]
} {SQLITE4_CONSTRAINT {t2.a may not be NULL}}

do_test capi2-3.20 {
  execsql {
    CREATE TABLE a1(message_id, name , UNIQUE(message_id, name) );
    INSERT INTO a1 VALUES(1, 1);
  }
} {}
do_test capi2-3.21 {
  set VM [sqlite4_prepare $DB {INSERT INTO a1 VALUES(1, 1)} -1 TAIL]
  sqlite4_step $VM
} {SQLITE4_ERROR}
do_test capi2-3.22 {
  sqlite4_errcode $DB
} {SQLITE4_ERROR}
do_test capi2-3.23 {
  sqlite4_finalize $VM
} {SQLITE4_CONSTRAINT}
do_test capi2-3.24 {
  sqlite4_errcode $DB
} {SQLITE4_CONSTRAINT}

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
#
# do_test capi2-6.2 {
#   list [sqlite4_step $VM1] \
#        [sqlite4_column_count $VM1] \
#        [get_row_values $VM1] \
#        [get_column_names $VM1]
# } {SQLITE4_BUSY 0 {} {}}
do_test capi2-6.5 {
  catchsql {INSERT INTO t3 VALUES(10);} db2
} {0 {}}
do_test capi2-6.3 {
  execsql {COMMIT} db2
} {}
do_test capi2-6.4 {
  list [sqlite4_step $VM1] \
       [sqlite4_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE4_ROW 1 1 {x counter}}



do_test capi2-6.6 {
  list [sqlite4_step $VM1] \
       [sqlite4_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE4_ROW 1 2 {x counter}}
do_test capi2-6.7 {







<
<
<









>
>
>







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
#
# do_test capi2-6.2 {
#   list [sqlite4_step $VM1] \
#        [sqlite4_column_count $VM1] \
#        [get_row_values $VM1] \
#        [get_column_names $VM1]
# } {SQLITE4_BUSY 0 {} {}}



do_test capi2-6.3 {
  execsql {COMMIT} db2
} {}
do_test capi2-6.4 {
  list [sqlite4_step $VM1] \
       [sqlite4_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE4_ROW 1 1 {x counter}}
do_test capi2-6.5 {
  catchsql {INSERT INTO t3 VALUES(10);} db2
} {1 {database is locked}}
do_test capi2-6.6 {
  list [sqlite4_step $VM1] \
       [sqlite4_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE4_ROW 1 2 {x counter}}
do_test capi2-6.7 {
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
    PRAGMA count_changes=on
  }
} {0}
do_test capi2-7.3 {
  stepsql $DB {
    UPDATE t1 SET a=a+10;
  }
} {0}
do_test capi2-7.4 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+1,b+1,c+1 FROM t1;
  }
} {0}
do_test capi2-7.4b {sqlite4_changes $DB} {1}
do_test capi2-7.5 {
  stepsql $DB {
    UPDATE t1 SET a=a+10;
  }
} {0}
do_test capi2-7.5b {sqlite4_changes $DB} {2}
do_test capi2-7.6 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4}
do_test capi2-7.7 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+2,b+2,c+2 FROM t1;
  }
} {0}
do_test capi2-7.8 {
  sqlite4_changes $DB
} {2}
do_test capi2-7.9 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4 23 4 5 24 5 6}
do_test capi2-7.10 {
  stepsql $DB {
    UPDATE t1 SET a=a-20;
    SELECT * FROM t1;
  }
} {0 1 2 3 2 3 4 3 4 5 4 5 6}

# Update for version 3: A SELECT statement no longer resets the change
# counter (Test result changes from 0 to 4).
do_test capi2-7.11 {
  sqlite4_changes $DB
} {4}
do_test capi2-7.11a {







|




|





|










|













|







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
    PRAGMA count_changes=on
  }
} {0}
do_test capi2-7.3 {
  stepsql $DB {
    UPDATE t1 SET a=a+10;
  }
} {0 1}
do_test capi2-7.4 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+1,b+1,c+1 FROM t1;
  }
} {0 1}
do_test capi2-7.4b {sqlite4_changes $DB} {1}
do_test capi2-7.5 {
  stepsql $DB {
    UPDATE t1 SET a=a+10;
  }
} {0 2}
do_test capi2-7.5b {sqlite4_changes $DB} {2}
do_test capi2-7.6 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4}
do_test capi2-7.7 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+2,b+2,c+2 FROM t1;
  }
} {0 2}
do_test capi2-7.8 {
  sqlite4_changes $DB
} {2}
do_test capi2-7.9 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4 23 4 5 24 5 6}
do_test capi2-7.10 {
  stepsql $DB {
    UPDATE t1 SET a=a-20;
    SELECT * FROM t1;
  }
} {0 4 1 2 3 2 3 4 3 4 5 4 5 6}

# Update for version 3: A SELECT statement no longer resets the change
# counter (Test result changes from 0 to 4).
do_test capi2-7.11 {
  sqlite4_changes $DB
} {4}
do_test capi2-7.11a {
Changes to test/capi3.test.
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
# capi3-5.*: Test the various sqlite4_result_* APIs
# capi3-6.*: Test that sqlite4_close fails if there are outstanding VMs.
#

set DB [sqlite4_connection_pointer db]

do_test capi3-1.0 {
  sqlite4_db_transaction_status $DB
} 0
do_test capi3-1.1 {
  set STMT [sqlite4_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL]
  sqlite4_finalize $STMT
  set TAIL
} {}
do_test capi3-1.2.1 {
  sqlite4_errcode $DB
} {SQLITE4_OK}
do_test capi3-1.2.2 {
  sqlite4_errcode $DB
} {SQLITE4_OK}
do_test capi3-1.3 {
  sqlite4_errmsg $DB
} {not an error}
do_test capi3-1.4 {
  set sql {SELECT name FROM sqlite_master;SELECT 10}
  set STMT [sqlite4_prepare $DB $sql -1 TAIL]







|
|









|







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
# capi3-5.*: Test the various sqlite4_result_* APIs
# capi3-6.*: Test that sqlite4_close fails if there are outstanding VMs.
#

set DB [sqlite4_connection_pointer db]

do_test capi3-1.0 {
  sqlite4_get_autocommit $DB
} 1
do_test capi3-1.1 {
  set STMT [sqlite4_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL]
  sqlite4_finalize $STMT
  set TAIL
} {}
do_test capi3-1.2.1 {
  sqlite4_errcode $DB
} {SQLITE4_OK}
do_test capi3-1.2.2 {
  sqlite4_extended_errcode $DB
} {SQLITE4_OK}
do_test capi3-1.3 {
  sqlite4_errmsg $DB
} {not an error}
do_test capi3-1.4 {
  set sql {SELECT name FROM sqlite_master;SELECT 10}
  set STMT [sqlite4_prepare $DB $sql -1 TAIL]
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
    set STMT [sqlite4_prepare $DB $sql -1 TAIL]
  }
} {1}
do_test capi3-1.8.1 {
  sqlite4_errcode $DB
} {SQLITE4_ERROR}
do_test capi3-1.8.2 {


























  sqlite4_errcode $DB
} {SQLITE4_ERROR}
do_test capi3-1.9 {



  sqlite4_errmsg $DB
} {no such column: namex}


















# rename sqlite4_open sqlite4_open_old
# proc sqlite4_open {fname options} {sqlite4_open_new $fname $options}

do_test capi3-3.1 {
  set db2 [sqlite4_open test.db {}]
  sqlite4_errcode $db2
} {SQLITE4_OK}
# FIX ME: Should test the db handle works.
do_test capi3-3.2 {
  sqlite4_close $db2
} {SQLITE4_OK}
do_test capi3-3.3 {
  catch {
    set db2 [sqlite4_open /bogus/path/test.db {}]
  }
  sqlite4_errcode $db2
} {SQLITE4_CANTOPEN}
do_test capi3-3.4 {
  sqlite4_errmsg $db2
} {unable to open database file}
do_test capi3-3.5 {
  sqlite4_close $db2
} {SQLITE4_OK}
do_test capi3-3.6.1-misuse {
  sqlite4_close $db2
} {SQLITE4_MISUSE}
do_test capi3-3.6.2-misuse {
  sqlite4_errmsg $db2
} {library routine called out of sequence}






do_test capi3-3.7 {
  set db2 [sqlite4_open]
  sqlite4_errcode $db2
} {SQLITE4_OK}
do_test capi3-3.8 {
  sqlite4_close $db2
} {SQLITE4_OK}

# rename sqlite4_open ""
# rename sqlite4_open_old sqlite4_open
























# This proc is used to test the following API calls:
#
# sqlite4_column_count
# sqlite4_column_name
# sqlite4_column_name16
# sqlite4_column_decltype







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
















|













>
>
>
>
>











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







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
    set STMT [sqlite4_prepare $DB $sql -1 TAIL]
  }
} {1}
do_test capi3-1.8.1 {
  sqlite4_errcode $DB
} {SQLITE4_ERROR}
do_test capi3-1.8.2 {
  sqlite4_extended_errcode $DB
} {SQLITE4_ERROR}
do_test capi3-1.9 {
  sqlite4_errmsg $DB
} {no such column: namex}

ifcapable {utf16} {
  do_test capi3-2.1 {
    set sql16 [utf16 {SELECT name FROM sqlite_master}]
    set STMT [sqlite4_prepare16 $DB $sql16 -1 ::TAIL]
    sqlite4_finalize $STMT
    utf8 $::TAIL
  } {}
  do_test capi3-2.2 {
    set sql [utf16 {SELECT name FROM sqlite_master;SELECT 10}]
    set STMT [sqlite4_prepare16 $DB $sql -1 TAIL]
    sqlite4_finalize $STMT
    utf8 $TAIL
  } {SELECT 10}
  do_test capi3-2.3 {
    set sql [utf16 {SELECT namex FROM sqlite_master}]
    catch {
      set STMT [sqlite4_prepare16 $DB $sql -1]
    }
  } {1}
  do_test capi3-2.4.1 {
    sqlite4_errcode $DB
  } {SQLITE4_ERROR}
  do_test capi3-2.4.2 {
    sqlite4_extended_errcode $DB
  } {SQLITE4_ERROR}
  do_test capi3-2.5 {
    sqlite4_errmsg $DB
  } {no such column: namex}

  ifcapable schema_pragmas {
    do_test capi3-2.6 {
      execsql {CREATE TABLE tablename(x)}
      set sql16 [utf16 {PRAGMA table_info("TableName"); --excess text}]
      set STMT [sqlite4_prepare16 $DB $sql16 -1]
      sqlite4_step $STMT
    } SQLITE4_ROW
    do_test capi3-2.7 {
      sqlite4_step $STMT
    } SQLITE4_DONE
    do_test capi3-2.8 {
      sqlite4_finalize $STMT
    } SQLITE4_OK
  }

} ;# endif utf16

# rename sqlite4_open sqlite4_open_old
# proc sqlite4_open {fname options} {sqlite4_open_new $fname $options}

do_test capi3-3.1 {
  set db2 [sqlite4_open test.db {}]
  sqlite4_errcode $db2
} {SQLITE4_OK}
# FIX ME: Should test the db handle works.
do_test capi3-3.2 {
  sqlite4_close $db2
} {SQLITE4_OK}
do_test capi3-3.3 {
  catch {
    set db2 [sqlite4_open /bogus/path/test.db {}]
  }
  sqlite4_extended_errcode $db2
} {SQLITE4_CANTOPEN}
do_test capi3-3.4 {
  sqlite4_errmsg $db2
} {unable to open database file}
do_test capi3-3.5 {
  sqlite4_close $db2
} {SQLITE4_OK}
do_test capi3-3.6.1-misuse {
  sqlite4_close $db2
} {SQLITE4_MISUSE}
do_test capi3-3.6.2-misuse {
  sqlite4_errmsg $db2
} {library routine called out of sequence}
ifcapable {utf16} {
  do_test capi3-3.6.3-misuse {
    utf8 [sqlite4_errmsg16 $db2]
  } {library routine called out of sequence}
}

do_test capi3-3.7 {
  set db2 [sqlite4_open]
  sqlite4_errcode $db2
} {SQLITE4_OK}
do_test capi3-3.8 {
  sqlite4_close $db2
} {SQLITE4_OK}

# rename sqlite4_open ""
# rename sqlite4_open_old sqlite4_open

ifcapable {utf16} {
do_test capi3-4.1 {
  set db2 [sqlite4_open16 [utf16 test.db] {}]
  sqlite4_errcode $db2
} {SQLITE4_OK}
# FIX ME: Should test the db handle works.
do_test capi3-4.2 {
  sqlite4_close $db2
} {SQLITE4_OK}
do_test capi3-4.3 {
  catch {
    set db2 [sqlite4_open16 [utf16 /bogus/path/test.db] {}]
  }
  sqlite4_errcode $db2
} {SQLITE4_CANTOPEN}
do_test capi3-4.4 {
  utf8 [sqlite4_errmsg16 $db2]
} {unable to open database file}
do_test capi3-4.5 {
  sqlite4_close $db2
} {SQLITE4_OK}
} ;# utf16

# This proc is used to test the following API calls:
#
# sqlite4_column_count
# sqlite4_column_name
# sqlite4_column_name16
# sqlite4_column_decltype
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

  # Column names in UTF-8
  do_test $test.1 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite4_column_name $STMT $i]} 
    set cnamelist
  } $names












  # Column names in UTF-8
  do_test $test.3 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite4_column_name $STMT $i]} 
    set cnamelist
  } $names












  # Column names in UTF-8
  do_test $test.5 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite4_column_decltype $STMT $i]} 
    set cnamelist
  } $decltypes













  # Test some out of range conditions:
  ifcapable {utf16} {
    do_test $test.7 {
      list \
        [sqlite4_column_name $STMT -1] \

        [sqlite4_column_decltype $STMT -1] \

        [sqlite4_column_name $STMT $numcols] \

        [sqlite4_column_decltype $STMT $numcols] \

    } {{} {} {} {}}
  }
} 

# This proc is used to test the following API calls:
#
# sqlite4_column_origin_name
# sqlite4_column_origin_name16







>
>
>
>
>
>
>
>
>
>
>







>
>
>
>
>
>
>
>
>
>
>







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






>

>

>

>
|







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

  # Column names in UTF-8
  do_test $test.1 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite4_column_name $STMT $i]} 
    set cnamelist
  } $names

  # Column names in UTF-16
  ifcapable {utf16} {
    do_test $test.2 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [utf8 [sqlite4_column_name16 $STMT $i]]
      }
      set cnamelist
    } $names
  }

  # Column names in UTF-8
  do_test $test.3 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite4_column_name $STMT $i]} 
    set cnamelist
  } $names

  # Column names in UTF-16
  ifcapable {utf16} {
    do_test $test.4 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [utf8 [sqlite4_column_name16 $STMT $i]]
      }
      set cnamelist
    } $names
  }

  # Column names in UTF-8
  do_test $test.5 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite4_column_decltype $STMT $i]} 
    set cnamelist
  } $decltypes

  # Column declaration types in UTF-16
  ifcapable {utf16} {
    do_test $test.6 {
      set cnamelist [list]
      foreach i $idxlist {
        lappend cnamelist [utf8 [sqlite4_column_decltype16 $STMT $i]]
      }
      set cnamelist
    } $decltypes
  }


  # Test some out of range conditions:
  ifcapable {utf16} {
    do_test $test.7 {
      list \
        [sqlite4_column_name $STMT -1] \
        [sqlite4_column_name16 $STMT -1] \
        [sqlite4_column_decltype $STMT -1] \
        [sqlite4_column_decltype16 $STMT -1] \
        [sqlite4_column_name $STMT $numcols] \
        [sqlite4_column_name16 $STMT $numcols] \
        [sqlite4_column_decltype $STMT $numcols] \
        [sqlite4_column_decltype16 $STMT $numcols]
    } {{} {} {} {} {} {} {} {}}
  }
} 

# This proc is used to test the following API calls:
#
# sqlite4_column_origin_name
# sqlite4_column_origin_name16
343
344
345
346
347
348
349
350






























351
352
353
354
355
356
357
358
359

# Integers
do_test $test.2 {
  set ints [list]
  foreach i $idxlist {lappend ints [sqlite4_column_int64 $STMT $i]}
  set ints
} $ints































# Blob
if {$test == "capi3-5.7"} breakpoint
do_test $test.5 {
  set utf8 [list]
  foreach i $idxlist {lappend utf8 [sqlite4_column_blob $STMT $i]}
  set utf8
} $strings

# UTF-8








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

<







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

# Integers
do_test $test.2 {
  set ints [list]
  foreach i $idxlist {lappend ints [sqlite4_column_int64 $STMT $i]}
  set ints
} $ints

# bytes
set lens [list]
foreach i $::idxlist {
  lappend lens [string length [lindex $strings $i]]
}
do_test $test.3 {
  set bytes [list]
  set lens [list]
  foreach i $idxlist {
    lappend bytes [sqlite4_column_bytes $STMT $i]
  }
  set bytes
} $lens

# bytes16
ifcapable {utf16} {
  set lens [list]
  foreach i $::idxlist {
    lappend lens [expr 2 * [string length [lindex $strings $i]]]
  }
  do_test $test.4 {
    set bytes [list]
    set lens [list]
    foreach i $idxlist {
      lappend bytes [sqlite4_column_bytes16 $STMT $i]
    }
    set bytes
  } $lens
}

# Blob

do_test $test.5 {
  set utf8 [list]
  foreach i $idxlist {lappend utf8 [sqlite4_column_blob $STMT $i]}
  set utf8
} $strings

# UTF-8
533
534
535
536
537
538
539














540
541
542
543
544
545
546
}

# This procedure returns the value of the file-format in file 'test.db'.
# 
proc get_file_format {{fname test.db}} {
  return [hexio_get_int [hexio_read $fname 44 4]]
}















if {![sqlite4 -has-codec]} {
  # Now test that the library correctly handles bogus entries in the
  # sqlite_master table (schema corruption).
  do_test capi3-8.1 {
    forcedelete test.db test.db-journal
    sqlite4 db test.db







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







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
}

# This procedure returns the value of the file-format in file 'test.db'.
# 
proc get_file_format {{fname test.db}} {
  return [hexio_get_int [hexio_read $fname 44 4]]
}

if {![sqlite4 -has-codec]} {
  # Test what happens when the library encounters a newer file format.
  do_test capi3-7.1 {
    set_file_format 5
  } {}
  do_test capi3-7.2 {
    catch { sqlite4 db test.db }
    catchsql {
      SELECT * FROM sqlite_master;
    }
  } {1 {unsupported file format}}
  db close
}

if {![sqlite4 -has-codec]} {
  # Now test that the library correctly handles bogus entries in the
  # sqlite_master table (schema corruption).
  do_test capi3-8.1 {
    forcedelete test.db test.db-journal
    sqlite4 db test.db
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
    BEGIN;
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 'int');
    INSERT INTO t1 VALUES(2, 'notatype');
  }
} {}
do_test capi3-11.1.1 {
  sqlite4_db_transaction_status $DB
} 1
do_test capi3-11.2 {
  set STMT [sqlite4_prepare $DB "SELECT func(b, a) FROM t1" -1 TAIL]
  sqlite4_step $STMT
} {SQLITE4_ROW}

# As of 3.6.5 a COMMIT is OK during while a query is still running -
# as long as it is a read-only query and not an incremental BLOB write.
#
do_test capi3-11.3.1 {
  catchsql {
    COMMIT;
  }
} {0 {}}
do_test capi3-11.3.2 {
  sqlite4_errcode $DB
} {SQLITE4_OK}
do_test capi3-11.3.3 {
  sqlite4_db_transaction_status $DB
} 0




do_test capi3-11.4 {
  sqlite4_step $STMT
} {SQLITE4_ERROR}
do_test capi3-11.5 {
  sqlite4_finalize $STMT
} {SQLITE4_ERROR}
do_test capi3-11.6 {
  catchsql {
    SELECT * FROM t1;
  }
} {0 {1 int 2 notatype}}
do_test capi3-11.7 {
  sqlite4_db_transaction_status $DB
} 0
do_test capi3-11.8 {
  execsql {
    CREATE TABLE t2(a);
    INSERT INTO t2 VALUES(1);
    INSERT INTO t2 VALUES(2);
    BEGIN;
    INSERT INTO t2 VALUES(3);
  }
} {}
do_test capi3-11.8.1 {
  sqlite4_db_transaction_status $DB
} 1
do_test capi3-11.9 {
  set STMT [sqlite4_prepare $DB "SELECT a FROM t2" -1 TAIL]
  sqlite4_step $STMT
} {SQLITE4_ROW}
do_test capi3-11.9.1 {
  sqlite4_db_transaction_status $DB
} 1
do_test capi3-11.9.2 {
  catchsql {
    ROLLBACK;
  }
} {1 {cannot rollback transaction - SQL statements in progress}}
do_test capi3-11.9.3 {
  sqlite4_db_transaction_status $DB
} 1
do_test capi3-11.10 {
  sqlite4_step $STMT
} {SQLITE4_ROW}
do_test capi3-11.11 {
  sqlite4_step $STMT
} {SQLITE4_ROW}
do_test capi3-11.12 {
  sqlite4_step $STMT
} {SQLITE4_DONE}
do_test capi3-11.13 {
  sqlite4_finalize $STMT
} {SQLITE4_OK}
do_test capi3-11.14 {
  execsql {
    SELECT a FROM t2;
  }
} {1 2 3}
do_test capi3-11.14.1 {
  sqlite4_db_transaction_status $DB
} 1
do_test capi3-11.15 {
  catchsql {
    ROLLBACK;
  }
} {0 {}}
do_test capi3-11.15.1 {
  sqlite4_db_transaction_status $DB
} 0
do_test capi3-11.16 {
  execsql {
    SELECT a FROM t2;
  }
} {1 2}

# Sanity check on the definition of 'outstanding VM'. This means any VM







|
|














|


|
|
>
>
>













|
|










|
|





|
|






|
|


















|
|






|
|







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
    BEGIN;
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 'int');
    INSERT INTO t1 VALUES(2, 'notatype');
  }
} {}
do_test capi3-11.1.1 {
  sqlite4_get_autocommit $DB
} 0
do_test capi3-11.2 {
  set STMT [sqlite4_prepare $DB "SELECT func(b, a) FROM t1" -1 TAIL]
  sqlite4_step $STMT
} {SQLITE4_ROW}

# As of 3.6.5 a COMMIT is OK during while a query is still running -
# as long as it is a read-only query and not an incremental BLOB write.
#
do_test capi3-11.3.1 {
  catchsql {
    COMMIT;
  }
} {0 {}}
do_test capi3-11.3.2 {
  sqlite4_extended_errcode $DB
} {SQLITE4_OK}
do_test capi3-11.3.3 {
  sqlite4_get_autocommit $DB
} 1
do_test capi3-11.3.4 {
  db eval {PRAGMA lock_status}
} {main shared temp closed}

do_test capi3-11.4 {
  sqlite4_step $STMT
} {SQLITE4_ERROR}
do_test capi3-11.5 {
  sqlite4_finalize $STMT
} {SQLITE4_ERROR}
do_test capi3-11.6 {
  catchsql {
    SELECT * FROM t1;
  }
} {0 {1 int 2 notatype}}
do_test capi3-11.7 {
  sqlite4_get_autocommit $DB
} 1
do_test capi3-11.8 {
  execsql {
    CREATE TABLE t2(a);
    INSERT INTO t2 VALUES(1);
    INSERT INTO t2 VALUES(2);
    BEGIN;
    INSERT INTO t2 VALUES(3);
  }
} {}
do_test capi3-11.8.1 {
  sqlite4_get_autocommit $DB
} 0
do_test capi3-11.9 {
  set STMT [sqlite4_prepare $DB "SELECT a FROM t2" -1 TAIL]
  sqlite4_step $STMT
} {SQLITE4_ROW}
do_test capi3-11.9.1 {
  sqlite4_get_autocommit $DB
} 0
do_test capi3-11.9.2 {
  catchsql {
    ROLLBACK;
  }
} {1 {cannot rollback transaction - SQL statements in progress}}
do_test capi3-11.9.3 {
  sqlite4_get_autocommit $DB
} 0
do_test capi3-11.10 {
  sqlite4_step $STMT
} {SQLITE4_ROW}
do_test capi3-11.11 {
  sqlite4_step $STMT
} {SQLITE4_ROW}
do_test capi3-11.12 {
  sqlite4_step $STMT
} {SQLITE4_DONE}
do_test capi3-11.13 {
  sqlite4_finalize $STMT
} {SQLITE4_OK}
do_test capi3-11.14 {
  execsql {
    SELECT a FROM t2;
  }
} {1 2 3}
do_test capi3-11.14.1 {
  sqlite4_get_autocommit $DB
} 0
do_test capi3-11.15 {
  catchsql {
    ROLLBACK;
  }
} {0 {}}
do_test capi3-11.15.1 {
  sqlite4_get_autocommit $DB
} 1
do_test capi3-11.16 {
  execsql {
    SELECT a FROM t2;
  }
} {1 2}

# Sanity check on the definition of 'outstanding VM'. This means any VM
1038
1039
1040
1041
1042
1043
1044
1045











1046
# Ticket #3134.  Prepare a statement with an nBytes parameter of 0.
# Make sure this works correctly and does not reference memory out of
# range.
#
do_test capi3-19.1 {
  sqlite4_prepare_tkt3134 db
} {}












finish_test








>
>
>
>
>
>
>
>
>
>
>

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
# Ticket #3134.  Prepare a statement with an nBytes parameter of 0.
# Make sure this works correctly and does not reference memory out of
# range.
#
do_test capi3-19.1 {
  sqlite4_prepare_tkt3134 db
} {}

# Tests of the interface when no VFS is registered.
#
if {![info exists tester_do_binarylog]} {
  db close
  vfs_unregister_all
  do_test capi3-20.1 {
    sqlite4_sleep 100
  } {0}
  vfs_reregister_all
}

finish_test
Changes to test/check.test.
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    SELECT * FROM t1;
  }
} {4 11.0}

do_test check-2.1 {
  execsql {
    CREATE TABLE t2(
      x INTEGER CHECK( typeof(coalesce(x,0))=='integer' ),
      y REAL CHECK( typeof(coalesce(y,0.1))=='real' ),
      z TEXT CHECK( typeof(coalesce(z,''))=='text' )
    );
  }
} {}
do_test check-2.2 {
  execsql {







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    SELECT * FROM t1;
  }
} {4 11.0}

do_test check-2.1 {
  execsql {
    CREATE TABLE t2(
      x INTEGER CHECK( typeof(coalesce(x,0))=="integer" ),
      y REAL CHECK( typeof(coalesce(y,0.1))=='real' ),
      z TEXT CHECK( typeof(coalesce(z,''))=='text' )
    );
  }
} {}
do_test check-2.2 {
  execsql {
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
} {1 {constraint failed}}
do_test check-2.5 {
  catchsql {
    INSERT INTO t2 VALUES(NULL, 5, NULL);
  }
} {1 {constraint failed}}
do_test check-2.6 {
  # This does not fail with src4. As CHECK constraints are evaluated after
  # affinities are applied.
  catchsql {
    INSERT INTO t2 VALUES(NULL, NULL, 3.14159);
  }

} {0 {}}
ifcapable subquery {
  do_test check-3.1 {
    catchsql {
      CREATE TABLE t3(
        x, y, z,
        CHECK( x<(SELECT min(x) FROM t1) )
      );







<
<



>
|







144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159
160
161
162
} {1 {constraint failed}}
do_test check-2.5 {
  catchsql {
    INSERT INTO t2 VALUES(NULL, 5, NULL);
  }
} {1 {constraint failed}}
do_test check-2.6 {


  catchsql {
    INSERT INTO t2 VALUES(NULL, NULL, 3.14159);
  }
} {1 {constraint failed}}

ifcapable subquery {
  do_test check-3.1 {
    catchsql {
      CREATE TABLE t3(
        x, y, z,
        CHECK( x<(SELECT min(x) FROM t1) )
      );
271
272
273
274
275
276
277







278
279
280
281
282
283
284
} {0 1}
do_test check-4.9 {
  catchsql {
    PRAGMA ignore_check_constraints=OFF;
    UPDATE t4 SET x=0, y=2;
  }
} {1 {constraint failed}}








do_test check-5.1 {
  catchsql {
    CREATE TABLE t5(x, y,
      CHECK( x*y<:abc )
    );
  }







>
>
>
>
>
>
>







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
} {0 1}
do_test check-4.9 {
  catchsql {
    PRAGMA ignore_check_constraints=OFF;
    UPDATE t4 SET x=0, y=2;
  }
} {1 {constraint failed}}
ifcapable vacuum {
  do_test check_4.10 {
    catchsql {
      VACUUM
    }
  } {0 {}}
}

do_test check-5.1 {
  catchsql {
    CREATE TABLE t5(x, y,
      CHECK( x*y<:abc )
    );
  }
Changes to test/coalesce.test.
65
66
67
68
69
70
71

72
73
74
75
76
77
78
  db eval {
    SELECT ifnull(nullif(a,4),99)
      FROM t1 ORDER BY a;
  }
} {1 2 3 99 5 6 7 8}
do_test coalesce-1.8 {
  db eval {

    SELECT coalesce(
      CASE WHEN b=2 THEN 123 END,
      CASE WHEN b=3 THEN 234 END,
      CASE WHEN c=3 THEN 345 WHEN c=33 THEN 456 END,
      d
    )
    FROM t1 ORDER BY a;







>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  db eval {
    SELECT ifnull(nullif(a,4),99)
      FROM t1 ORDER BY a;
  }
} {1 2 3 99 5 6 7 8}
do_test coalesce-1.8 {
  db eval {
pragma vdbe_listing=on;
    SELECT coalesce(
      CASE WHEN b=2 THEN 123 END,
      CASE WHEN b=3 THEN 234 END,
      CASE WHEN c=3 THEN 345 WHEN c=33 THEN 456 END,
      d
    )
    FROM t1 ORDER BY a;
Changes to test/collate2.test.
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
# Test that when one side has a default collation type and the other
# does not, the collation type is used.
do_test collate2-4.3 {
  execsql {
    SELECT collate2t1.a FROM collate2t1, collate2t3 
      WHERE collate2t1.b = collate2t3.b||'';
  }
} {AA Aa aA aa}
do_test collate2-4.4 {
  execsql {
    SELECT collate2t1.a FROM collate2t1, collate2t3 
      WHERE collate2t3.b||'' = collate2t1.b;
  }
} {AA Aa aA aa}

do_test collate2-4.5 {
  execsql {
    DROP TABLE collate2t3;
  }
} {}








|





|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
# Test that when one side has a default collation type and the other
# does not, the collation type is used.
do_test collate2-4.3 {
  execsql {
    SELECT collate2t1.a FROM collate2t1, collate2t3 
      WHERE collate2t1.b = collate2t3.b||'';
  }
} {aa aA Aa AA}
do_test collate2-4.4 {
  execsql {
    SELECT collate2t1.a FROM collate2t1, collate2t3 
      WHERE collate2t3.b||'' = collate2t1.b;
  }
} {aa aA Aa AA}

do_test collate2-4.5 {
  execsql {
    DROP TABLE collate2t3;
  }
} {}

Changes to test/collate4.test.
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
  execsql {
    DROP INDEX collate4i1;
    CREATE INDEX collate4i1 ON collate4t1(a, b, c COLLATE text);
  }
  count {
    SELECT * FROM collate4t2 NATURAL JOIN collate4t1;
  }
} {0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 25}

do_test collate4-2.2.10 {
  execsql {
    DROP TABLE collate4t1;
    DROP TABLE collate4t2;
  }
} {}







|







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
  execsql {
    DROP INDEX collate4i1;
    CREATE INDEX collate4i1 ON collate4t1(a, b, c COLLATE text);
  }
  count {
    SELECT * FROM collate4t2 NATURAL JOIN collate4t1;
  }
} {0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 33}

do_test collate4-2.2.10 {
  execsql {
    DROP TABLE collate4t1;
    DROP TABLE collate4t2;
  }
} {}
Deleted test/covidx.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
# 2013 July 23
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the COVERING clause of the CREATE 
# INDEX statement.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix covidx

#-------------------------------------------------------------------------
#
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  CREATE TABLE t2("123abc", "odd column name");
  CREATE TABLE "frivolous table name"(x, y);
}

foreach {tn sql res} {
  1 { t1(a) COVERING(a, b, c) }                   {0 {}}
  2 { t1(a) COVERING ALL }                        {0 {}}
  3 { t2("123abc") COVERING ("odd column name") } {0 {}}
  4 { "frivolous table name"(x) COVERING (y) }    {0 {}}

  5 { t1(c) COVERING (d) } {1 {table t1 has no column named d}}
  6 { t1(c) COVERING () }  {1 {near ")": syntax error}}
} {
  do_catchsql_test 1.$tn "CREATE INDEX i1 ON $sql" $res
  execsql { 
    DROP INDEX IF EXISTS i1;
  }
}

#-------------------------------------------------------------------------
#
do_execsql_test 2.1 {
  CREATE TABLE x1(x);
  CREATE INDEX xi1 ON x1(x) COVERING (x);
  CREATE INDEX xi2 ON x1(x) COVERING ALL   ;

  SELECT sql FROM sqlite_master where type = 'index';
} {
  {CREATE INDEX xi1 ON x1(x) COVERING (x)}
  {CREATE INDEX xi2 ON x1(x) COVERING ALL}
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3.1 {
  CREATE TABLE t1(a PRIMARY KEY, b, c);
  CREATE INDEX i1 ON t1(b) COVERING(c, b);
} {}
do_execsql_test 3.2 {
  INSERT INTO t1 VALUES(1, 'x', 'y');
} {}
do_execsql_test 3.3 {
  SELECT c FROM t1 ORDER BY b;
} {y}

finish_test

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














































































































































Changes to test/createtab.test.
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  } {4}

  set isUtf16 0
  ifcapable utf16 { 
    set isUtf16 [expr {[execsql {PRAGMA encoding}] != "UTF-8"}]
  }

  #do_test createtab-$av.2 {
  #  file size test.db
  #} [expr {1024*(4+($av!=0)+(${isUtf16}*2))}]
  
  # Start reading the table
  #
  do_test createtab-$av.3 {
    set STMT [sqlite4_prepare db {SELECT x FROM t1} -1 TAIL]
    sqlite4_step $STMT
  } {SQLITE4_ROW}







|
|
|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  } {4}

  set isUtf16 0
  ifcapable utf16 { 
    set isUtf16 [expr {[execsql {PRAGMA encoding}] != "UTF-8"}]
  }

  do_test createtab-$av.2 {
    file size test.db
  } [expr {1024*(4+($av!=0)+(${isUtf16}*2))}]
  
  # Start reading the table
  #
  do_test createtab-$av.3 {
    set STMT [sqlite4_prepare db {SELECT x FROM t1} -1 TAIL]
    sqlite4_step $STMT
  } {SQLITE4_ROW}
Changes to test/descidx1.test.
45
46
47
48
49
50
51

52
53
54
55
56

57
58
59
60
61
62
63
64
# Verify that the file format starts as 4.
#
do_test descidx1-1.1 {
  execsql {
    CREATE TABLE t1(a,b);
    CREATE INDEX i1 ON t1(b ASC);
  }

} {}
do_test descidx1-1.2 {
  execsql {
    CREATE INDEX i2 ON t1(a DESC);
  }

} {}

# Put some information in the table and verify that the descending
# index actually works.
#
do_test descidx1-2.1 {
  execsql {
    INSERT INTO t1 VALUES(1,1);







>
|




>
|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Verify that the file format starts as 4.
#
do_test descidx1-1.1 {
  execsql {
    CREATE TABLE t1(a,b);
    CREATE INDEX i1 ON t1(b ASC);
  }
  get_file_format
} {4}
do_test descidx1-1.2 {
  execsql {
    CREATE INDEX i2 ON t1(a DESC);
  }
  get_file_format
} {4}

# Put some information in the table and verify that the descending
# index actually works.
#
do_test descidx1-2.1 {
  execsql {
    INSERT INTO t1 VALUES(1,1);
284
285
286
287
288
289
290
291






































































292
  }
} {000 001 010 011 100 101 110 111 sort}
do_test descidx1-5.9 {
  cksort {
    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a DESC, b DESC, c ASC
  }
} {110 111 100 101 010 011 000 001 sort}







































































finish_test








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

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
  }
} {000 001 010 011 100 101 110 111 sort}
do_test descidx1-5.9 {
  cksort {
    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a DESC, b DESC, c ASC
  }
} {110 111 100 101 010 011 000 001 sort}

# Test the legacy_file_format pragma here because we have access to
# the get_file_format command.
#
ifcapable legacyformat {
  do_test descidx1-6.1 {
    db close
    forcedelete test.db test.db-journal
    sqlite4 db test.db
    execsql {PRAGMA legacy_file_format}
  } {1}
} else {
  do_test descidx1-6.1 {
    db close
    forcedelete test.db test.db-journal
    sqlite4 db test.db
    execsql {PRAGMA legacy_file_format}
  } {0}
}
do_test descidx1-6.2 {
  execsql {PRAGMA legacy_file_format=YES}
  execsql {PRAGMA legacy_file_format}
} {1}
do_test descidx1-6.3 {
  execsql {
    CREATE TABLE t1(a,b,c);
  }
  get_file_format
} {1}
ifcapable vacuum {
  # Verify that the file format is preserved across a vacuum.
  do_test descidx1-6.3.1 {
    execsql {VACUUM}
    get_file_format
  } {1}
}
do_test descidx1-6.4 {
  db close
  forcedelete test.db test.db-journal
  sqlite4 db test.db
  execsql {PRAGMA legacy_file_format=NO}
  execsql {PRAGMA legacy_file_format}
} {0}
do_test descidx1-6.5 {
  execsql {
    CREATE TABLE t1(a,b,c);
    CREATE INDEX i1 ON t1(a ASC, b DESC, c ASC);
    INSERT INTO t1 VALUES(1,2,3);
    INSERT INTO t1 VALUES(1,1,0);
    INSERT INTO t1 VALUES(1,2,1);
    INSERT INTO t1 VALUES(1,3,4);
  }
  get_file_format
} {4}
ifcapable vacuum {
  # Verify that the file format is preserved across a vacuum.
  do_test descidx1-6.6 {
    execsql {VACUUM}
    get_file_format
  } {4}
  do_test descidx1-6.7 {
    execsql {
      PRAGMA legacy_file_format=ON;
      VACUUM;
    }
    get_file_format
  } {4}
} 



finish_test
Changes to test/descidx2.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
# 2005 December 21
#
# 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.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is descending indices.
#



set testdir [file dirname $argv0]
source $testdir/tester.tcl



























# Verify that the file format starts as 4
#
do_test descidx2-1.1 {
  execsql {
    CREATE TABLE t1(a,b);
    CREATE INDEX i1 ON t1(b ASC);
  }

} {}
do_test descidx2-1.2 {
  execsql {
    CREATE INDEX i2 ON t1(a DESC);
  }

} {}













# Put some information in the table and verify that the DESC
# on the index is ignored.
#
do_test descidx2-2.1 {
  execsql {
    INSERT INTO t1 VALUES(1,1);
    INSERT INTO t1 VALUES(2,2);
    INSERT INTO t1 SELECT a+2, a+2 FROM t1;
    INSERT INTO t1 SELECT a+4, a+4 FROM t1;
    SELECT b FROM t1 WHERE a>3 AND a<7 ORDER BY b ASC;
  }
} {4 5 6}
do_test descidx2-2.2 {
  execsql {
    SELECT a FROM t1 WHERE b>3 AND b<7 ORDER BY a ASC;
  }
} {4 5 6}
do_test descidx2-2.3 {
  execsql {
    SELECT b FROM t1 WHERE a>=3 AND a<7 ORDER BY b ASC;
  }
} {3 4 5 6}
do_test descidx2-2.4 {
  execsql {
    SELECT b FROM t1 WHERE a>3 AND a<=7 ORDER BY b ASC;
  }
} {4 5 6 7}
do_test descidx2-2.5 {
  execsql {
    SELECT b FROM t1 WHERE a>=3 AND a<=7 ORDER BY b ASC;
  }
} {3 4 5 6 7}
do_test descidx2-2.6 {
  execsql {
    SELECT a FROM t1 WHERE b>=3 AND b<=7 ORDER BY a ASC;
  }
} {3 4 5 6 7}

# 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.
#













>
|
>


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









>
|




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










|




|




|




|




|




|







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
# 2005 December 21
#
# 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.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is descending indices.
#
# $Id: descidx2.test,v 1.5 2008/03/19 00:21:31 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec


db eval {PRAGMA legacy_file_format=OFF}

# This procedure sets the value of the file-format in file 'test.db'
# to $newval. Also, the schema cookie is incremented.
# 
proc set_file_format {newval} {
  hexio_write test.db 44 [hexio_render_int32 $newval]
  set schemacookie [hexio_get_int [hexio_read test.db 40 4]]
  incr schemacookie
  hexio_write test.db 40 [hexio_render_int32 $schemacookie]
  return {}
}

# This procedure returns the value of the file-format in file 'test.db'.
# 
proc get_file_format {{fname test.db}} {
  return [hexio_get_int [hexio_read $fname 44 4]]
}


# Verify that the file format starts as 4
#
do_test descidx2-1.1 {
  execsql {
    CREATE TABLE t1(a,b);
    CREATE INDEX i1 ON t1(b ASC);
  }
  get_file_format
} {4}
do_test descidx2-1.2 {
  execsql {
    CREATE INDEX i2 ON t1(a DESC);
  }
  get_file_format
} {4}

# Before adding any information to the database, set the file format
# back to three.  Then close and reopen the database.  With the file
# format set to three, SQLite should ignore the DESC argument on the
# index.
#
do_test descidx2-2.0 {
  set_file_format 3
  db close
  sqlite4 db test.db
  get_file_format
} {3}

# Put some information in the table and verify that the DESC
# on the index is ignored.
#
do_test descidx2-2.1 {
  execsql {
    INSERT INTO t1 VALUES(1,1);
    INSERT INTO t1 VALUES(2,2);
    INSERT INTO t1 SELECT a+2, a+2 FROM t1;
    INSERT INTO t1 SELECT a+4, a+4 FROM t1;
    SELECT b FROM t1 WHERE a>3 AND a<7;
  }
} {4 5 6}
do_test descidx2-2.2 {
  execsql {
    SELECT a FROM t1 WHERE b>3 AND b<7;
  }
} {4 5 6}
do_test descidx2-2.3 {
  execsql {
    SELECT b FROM t1 WHERE a>=3 AND a<7;
  }
} {3 4 5 6}
do_test descidx2-2.4 {
  execsql {
    SELECT b FROM t1 WHERE a>3 AND a<=7;
  }
} {4 5 6 7}
do_test descidx2-2.5 {
  execsql {
    SELECT b FROM t1 WHERE a>=3 AND a<=7;
  }
} {3 4 5 6 7}
do_test descidx2-2.6 {
  execsql {
    SELECT a FROM t1 WHERE b>=3 AND b<=7;
  }
} {3 4 5 6 7}

# 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.
#
Changes to test/descidx3.test.
22
23
24
25
26
27
28

29



















30
31
32
33
34
35

36
37
38
39
40
41
42
43
#
do_not_use_codec

ifcapable !bloblit {
  finish_test
  return
}





















do_test descidx3-1.1 {
  execsql {
    CREATE TABLE t1(i INTEGER PRIMARY KEY,a,b,c,d);
    CREATE INDEX t1i1 ON t1(a DESC, b ASC, c DESC);
    CREATE INDEX t1i2 ON t1(b DESC, c ASC, d DESC);
  }

} {}

# Put some information in the table and verify that the descending
# index actually works.
#
do_test descidx3-2.1 {
  execsql {
    INSERT INTO t1 VALUES(1, NULL, NULL, NULL, NULL);







>

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






>
|







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
#
do_not_use_codec

ifcapable !bloblit {
  finish_test
  return
}
db eval {PRAGMA legacy_file_format=OFF}

# This procedure sets the value of the file-format in file 'test.db'
# to $newval. Also, the schema cookie is incremented.
# 
proc set_file_format {newval} {
  hexio_write test.db 44 [hexio_render_int32 $newval]
  set schemacookie [hexio_get_int [hexio_read test.db 40 4]]
  incr schemacookie
  hexio_write test.db 40 [hexio_render_int32 $schemacookie]
  return {}
}

# This procedure returns the value of the file-format in file 'test.db'.
# 
proc get_file_format {{fname test.db}} {
  return [hexio_get_int [hexio_read $fname 44 4]]
}

# Verify that the file format starts as 4.
#
do_test descidx3-1.1 {
  execsql {
    CREATE TABLE t1(i INTEGER PRIMARY KEY,a,b,c,d);
    CREATE INDEX t1i1 ON t1(a DESC, b ASC, c DESC);
    CREATE INDEX t1i2 ON t1(b DESC, c ASC, d DESC);
  }
  get_file_format
} {4}

# Put some information in the table and verify that the descending
# index actually works.
#
do_test descidx3-2.1 {
  execsql {
    INSERT INTO t1 VALUES(1, NULL, NULL, NULL, NULL);
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
} {9 7 6 8 3 4 2 5}

ifcapable subquery {
  # If the subquery capability is not compiled in to the binary, then
  # the IN(...) operator is not available. Hence these tests cannot be 
  # run.
  do_test descidx3-4.1 {
    lsort [execsql {
      UPDATE t1 SET a=2 WHERE i<6;
      SELECT i FROM t1 WHERE a IN (1,2) AND b>0 AND b<'zzz';
    }]

  } {2 3 4 6 8}
  do_test descidx3-4.2 {
    execsql {
      UPDATE t1 SET a=1;
      SELECT i FROM t1 WHERE a IN (1,2) AND b>0 AND b<'zzz';
    }
  } {2 4 3 8 6}
  do_test descidx3-4.3 {







|


<
>
|







128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
} {9 7 6 8 3 4 2 5}

ifcapable subquery {
  # If the subquery capability is not compiled in to the binary, then
  # the IN(...) operator is not available. Hence these tests cannot be 
  # run.
  do_test descidx3-4.1 {
    execsql {
      UPDATE t1 SET a=2 WHERE i<6;
      SELECT i FROM t1 WHERE a IN (1,2) AND b>0 AND b<'zzz';

    }
  } {8 6 2 4 3}
  do_test descidx3-4.2 {
    execsql {
      UPDATE t1 SET a=1;
      SELECT i FROM t1 WHERE a IN (1,2) AND b>0 AND b<'zzz';
    }
  } {2 4 3 8 6}
  do_test descidx3-4.3 {
Changes to test/distinct.test.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# This file implements regression tests for SQLite library.  The
# focus of this script is the DISTINCT modifier.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !compound {
  finish_test
  return
}

set testprefix distinct


proc is_distinct_noop {sql} {
  set sql1 $sql
  set sql2 [string map {DISTINCT ""} $sql]








<
<
<
<
<







11
12
13
14
15
16
17





18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.  The
# focus of this script is the DISTINCT modifier.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl






set testprefix distinct


proc is_distinct_noop {sql} {
  set sql1 $sql
  set sql2 [string map {DISTINCT ""} $sql]

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
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  CREATE UNIQUE INDEX i1 ON t1(b, c);
  CREATE UNIQUE INDEX i2 ON t1(d COLLATE nocase);

  CREATE TABLE t2(x INTEGER PRIMARY KEY, y);

  CREATE TABLE t3(c1 PRIMARY KEY NOT NULL, c2 NOT NULL);
  CREATE INDEX i3 ON t3(c2);

  CREATE TABLE t4(a, b NOT NULL, c NOT NULL, d NOT NULL);
  CREATE UNIQUE INDEX t4i1 ON t4(b, c);
  CREATE UNIQUE INDEX t4i2 ON t4(d COLLATE nocase);
}
foreach {tn noop sql} {

  1.1 0   "SELECT DISTINCT b, c FROM t1"
  1.2 1   "SELECT DISTINCT b, c FROM t4"
  2.1 0   "SELECT DISTINCT c FROM t1 WHERE b = ?"
  2.2 1   "SELECT DISTINCT c FROM t4 WHERE b = ?"
  3   1   "SELECT DISTINCT rowid FROM t1"
  4   1   "SELECT DISTINCT rowid, a FROM t1"
  5   1   "SELECT DISTINCT x FROM t2"
  6   1   "SELECT DISTINCT * FROM t2"
  7   1   "SELECT DISTINCT * FROM (SELECT * FROM t2)"

  8.1 0   "SELECT DISTINCT * FROM t1"
  8.2 1   "SELECT DISTINCT * FROM t4"

  8   0   "SELECT DISTINCT a, b FROM t1"

  9   0   "SELECT DISTINCT c FROM t1 WHERE b IN (1,2)"
  10  0   "SELECT DISTINCT c FROM t1"
  11  0   "SELECT DISTINCT b FROM t1"

  12.1 0   "SELECT DISTINCT a, d FROM t1"
  12.2 0   "SELECT DISTINCT a, d FROM t4"
  13.1 0   "SELECT DISTINCT a, b, c COLLATE nocase FROM t1"
  13.2 0   "SELECT DISTINCT a, b, c COLLATE nocase FROM t4"
  14.1 0   "SELECT DISTINCT a, d COLLATE nocase FROM t1"
  14.2 1   "SELECT DISTINCT a, d COLLATE nocase FROM t4"

  15   0   "SELECT DISTINCT a, d COLLATE binary FROM t1"
  16.1 0   "SELECT DISTINCT a, b, c COLLATE binary FROM t1"
  16.2 1   "SELECT DISTINCT a, b, c COLLATE binary FROM t4"

  16  0   "SELECT DISTINCT t1.rowid FROM t1, t2"
  17  0   { /* Technically, it would be possible to detect that DISTINCT
            ** is a no-op in cases like the following. But SQLite does not
            ** do so. */
            SELECT DISTINCT t1.rowid FROM t1, t2 WHERE t1.rowid=t2.x }

  18  1   "SELECT DISTINCT c1, c2 FROM t3"
  19  1   "SELECT DISTINCT c1 FROM t3"
  20  1   "SELECT DISTINCT * FROM t3"
  21  0   "SELECT DISTINCT c2 FROM t3"

  22  0   "SELECT DISTINCT * FROM (SELECT 1, 2, 3 UNION SELECT 4, 5, 6)"

  24  0   "SELECT DISTINCT rowid/2 FROM t1"
  25  1   "SELECT DISTINCT rowid/2, rowid FROM t1"
  26.1  0   "SELECT DISTINCT rowid/2, b FROM t1 WHERE c = ?"
  26.2  1   "SELECT DISTINCT rowid/2, b FROM t4 WHERE c = ?"
} {
  if {$noop} {
    do_distinct_noop_test 1.$tn $sql
  } else {
    do_distinct_not_noop_test 1.$tn $sql
  }
}







|

<
<
<
<



<
|
|
<






<
|







|
<
|
<
|
<
<
|
|
<
















|
<







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
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d);
  CREATE UNIQUE INDEX i1 ON t1(b, c);
  CREATE UNIQUE INDEX i2 ON t1(d COLLATE nocase);

  CREATE TABLE t2(x INTEGER PRIMARY KEY, y);

  CREATE TABLE t3(c1 PRIMARY KEY, c2);
  CREATE INDEX i3 ON t3(c2);




}
foreach {tn noop sql} {


  1   1   "SELECT DISTINCT b, c FROM t1"
  2   1   "SELECT DISTINCT c FROM t1 WHERE b = ?"

  3   1   "SELECT DISTINCT rowid FROM t1"
  4   1   "SELECT DISTINCT rowid, a FROM t1"
  5   1   "SELECT DISTINCT x FROM t2"
  6   1   "SELECT DISTINCT * FROM t2"
  7   1   "SELECT DISTINCT * FROM (SELECT * FROM t2)"


  8   1   "SELECT DISTINCT * FROM t1"

  8   0   "SELECT DISTINCT a, b FROM t1"

  9   0   "SELECT DISTINCT c FROM t1 WHERE b IN (1,2)"
  10  0   "SELECT DISTINCT c FROM t1"
  11  0   "SELECT DISTINCT b FROM t1"

  12  0   "SELECT DISTINCT a, d FROM t1"

  13  0   "SELECT DISTINCT a, b, c COLLATE nocase FROM t1"

  14  1   "SELECT DISTINCT a, d COLLATE nocase FROM t1"


  15  0   "SELECT DISTINCT a, d COLLATE binary FROM t1"
  16  1   "SELECT DISTINCT a, b, c COLLATE binary FROM t1"


  16  0   "SELECT DISTINCT t1.rowid FROM t1, t2"
  17  0   { /* Technically, it would be possible to detect that DISTINCT
            ** is a no-op in cases like the following. But SQLite does not
            ** do so. */
            SELECT DISTINCT t1.rowid FROM t1, t2 WHERE t1.rowid=t2.x }

  18  1   "SELECT DISTINCT c1, c2 FROM t3"
  19  1   "SELECT DISTINCT c1 FROM t3"
  20  1   "SELECT DISTINCT * FROM t3"
  21  0   "SELECT DISTINCT c2 FROM t3"

  22  0   "SELECT DISTINCT * FROM (SELECT 1, 2, 3 UNION SELECT 4, 5, 6)"

  24  0   "SELECT DISTINCT rowid/2 FROM t1"
  25  1   "SELECT DISTINCT rowid/2, rowid FROM t1"
  26  1   "SELECT DISTINCT rowid/2, b FROM t1 WHERE c = ?"

} {
  if {$noop} {
    do_distinct_noop_test 1.$tn $sql
  } else {
    do_distinct_not_noop_test 1.$tn $sql
  }
}
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

foreach {tn sql temptables res} {
  1   "a, b FROM t1"                                       {}      {A B a b}
  2   "b, a FROM t1"                                       {}      {B A b a}
  3   "a, b, c FROM t1"                                    {hash}  {a b c A B C}
  4   "a, b, c FROM t1 ORDER BY a, b, c"                   {btree} {A B C a b c}
  5   "b FROM t1 WHERE a = 'a'"                            {}      {b}
  6   "b FROM t1 ORDER BY +b COLLATE binary"          {btree hash} {B b}
  7   "a FROM t1"                                          {}      {A a}
  8   "b COLLATE nocase FROM t1"                           {}      {b}
  9   "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {}      {B}
} {
  do_execsql_test    2.$tn.1 "SELECT DISTINCT $sql" $res
  # do_temptables_test 2.$tn.2 "SELECT DISTINCT $sql" $temptables
}

do_execsql_test 2.A {
  SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o ORDER BY rowid;
} {a A a A}

do_test 3.0 {
  db eval {
    CREATE TABLE t3(a INTEGER, b INTEGER, c, UNIQUE(a,b));
    INSERT INTO t3 VALUES
        (null, null, 1),
        (null, null, 2),
        (null, 3, 4),
        (null, 3, 5),
        (6, null, 7),
        (6, null, 8);
    SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b;
  }
} {{} {} {} 3 6 {}}
do_test 3.1 {
  regexp {OpenEphemeral} [db eval {
    EXPLAIN SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b;
  }]
} {0}

finish_test







|









|


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


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162










163






164
165

foreach {tn sql temptables res} {
  1   "a, b FROM t1"                                       {}      {A B a b}
  2   "b, a FROM t1"                                       {}      {B A b a}
  3   "a, b, c FROM t1"                                    {hash}  {a b c A B C}
  4   "a, b, c FROM t1 ORDER BY a, b, c"                   {btree} {A B C a b c}
  5   "b FROM t1 WHERE a = 'a'"                            {}      {b}
  6   "b FROM t1"                                          {hash}  {b B}
  7   "a FROM t1"                                          {}      {A a}
  8   "b COLLATE nocase FROM t1"                           {}      {b}
  9   "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {}      {B}
} {
  do_execsql_test    2.$tn.1 "SELECT DISTINCT $sql" $res
  # do_temptables_test 2.$tn.2 "SELECT DISTINCT $sql" $temptables
}

do_execsql_test 2.A {
  SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o;
} {a A a A}




















finish_test
Changes to test/e_createtable.test.
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
do_createtable_tests 1.1.1 -error {
  object name reserved for internal use: %s
} {
  1    "CREATE TABLE sqlite_abc(a, b, c)"        sqlite_abc
  2    "CREATE TABLE temp.sqlite_helloworld(x)"  sqlite_helloworld
  3    {CREATE TABLE auxa."sqlite__"(x, y)}      sqlite__
  4    {CREATE TABLE auxb."sqlite_"(z)}          sqlite_
  5    {CREATE TABLE "SQLITE_TBL"(z)}            SQLITE_TBL
}
do_createtable_tests 1.1.2 {
  1    "CREATE TABLE sqlit_abc(a, b, c)"         {}
  2    "CREATE TABLE temp.sqlitehelloworld(x)"   {}
  3    {CREATE TABLE auxa."sqlite"(x, y)}        {}
  4    {CREATE TABLE auxb."sqlite-"(z)}          {}
  5    {CREATE TABLE "SQLITE-TBL"(z)}            {}







|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
do_createtable_tests 1.1.1 -error {
  object name reserved for internal use: %s
} {
  1    "CREATE TABLE sqlite_abc(a, b, c)"        sqlite_abc
  2    "CREATE TABLE temp.sqlite_helloworld(x)"  sqlite_helloworld
  3    {CREATE TABLE auxa."sqlite__"(x, y)}      sqlite__
  4    {CREATE TABLE auxb."sqlite_"(z)}          sqlite_
  5    {CREATE TABLE "SQLITE4_TBL"(z)}            SQLITE4_TBL
}
do_createtable_tests 1.1.2 {
  1    "CREATE TABLE sqlit_abc(a, b, c)"         {}
  2    "CREATE TABLE temp.sqlitehelloworld(x)"   {}
  3    {CREATE TABLE auxa."sqlite"(x, y)}        {}
  4    {CREATE TABLE auxb."sqlite-"(z)}          {}
  5    {CREATE TABLE "SQLITE-TBL"(z)}            {}
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
#
#   table_column_decltypes TBL
#     The argument must be a table name. Return a list of column declared
#     types, from left to right, for the table.
#
proc sci {select cmd} {
  set res [list]
  set STMT [sqlite4_prepare db $select -1 dummy]
  for {set i 0} {$i < [sqlite4_column_count $STMT]} {incr i} {
    lappend res [$cmd $STMT $i]
  }
  sqlite4_finalize $STMT
  set res
}
proc tci {tbl cmd} { sci "SELECT * FROM $tbl" $cmd }







|







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
#
#   table_column_decltypes TBL
#     The argument must be a table name. Return a list of column declared
#     types, from left to right, for the table.
#
proc sci {select cmd} {
  set res [list]
  set STMT [sqlite4_prepare_v2 db $select -1 dummy]
  for {set i 0} {$i < [sqlite4_column_count $STMT]} {incr i} {
    lappend res [$cmd $STMT $i]
  }
  sqlite4_finalize $STMT
  set res
}
proc tci {tbl cmd} { sci "SELECT * FROM $tbl" $cmd }
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
set sqlite_current_time 1000000000
do_createtable_tests 3.5 -query {
  SELECT quote(a), quote(b), quote(c), quote(d), quote(e), quote(f), 
         quote(g), quote(h), quote(i), quote(j), quote(k)
  FROM t4 ORDER BY rowid DESC LIMIT 1;
} {
  1 "INSERT INTO t4 DEFAULT VALUES" {
    NULL {'string constant'} x'424c4f42' 1 -1 3.14 -3.14 
    'acd' '01:46:40' '2001-09-09' {'2001-09-09 01:46:40'}
  }

  2 "INSERT INTO t4(a, b, c) VALUES(1, 2, 3)" {
    1 2 3 1 -1 3.14 -3.14 'acd' '01:46:40' '2001-09-09' {'2001-09-09 01:46:40'}
  }

  3 "INSERT INTO t4(k, j, i) VALUES(1, 2, 3)" {
    NULL {'string constant'} x'424c4f42' 1 -1 3.14 -3.14 'acd' 3 2 1
  }

  4 "INSERT INTO t4(a,b,c,d,e,f,g,h,i,j,k) VALUES(1,2,3,4,5,6,7,8,9,10,11)" {
    1 2 3 4 5 6 7 8 9 10 11
  }
}








|








|







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
set sqlite_current_time 1000000000
do_createtable_tests 3.5 -query {
  SELECT quote(a), quote(b), quote(c), quote(d), quote(e), quote(f), 
         quote(g), quote(h), quote(i), quote(j), quote(k)
  FROM t4 ORDER BY rowid DESC LIMIT 1;
} {
  1 "INSERT INTO t4 DEFAULT VALUES" {
    NULL {'string constant'} X'424C4F42' 1 -1 3.14 -3.14 
    'acd' '01:46:40' '2001-09-09' {'2001-09-09 01:46:40'}
  }

  2 "INSERT INTO t4(a, b, c) VALUES(1, 2, 3)" {
    1 2 3 1 -1 3.14 -3.14 'acd' '01:46:40' '2001-09-09' {'2001-09-09 01:46:40'}
  }

  3 "INSERT INTO t4(k, j, i) VALUES(1, 2, 3)" {
    NULL {'string constant'} X'424C4F42' 1 -1 3.14 -3.14 'acd' 3 2 1
  }

  4 "INSERT INTO t4(a,b,c,d,e,f,g,h,i,j,k) VALUES(1,2,3,4,5,6,7,8,9,10,11)" {
    1 2 3 4 5 6 7 8 9 10 11
  }
}

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
    d DEFAULT -45678.6,
    e DEFAULT 394507
  );
} {}
do_execsql_test e_createtable-3.6.2 {
  INSERT INTO t5 DEFAULT VALUES;
  SELECT quote(a), quote(b), quote(c), quote(d), quote(e) FROM t5;
} {NULL {'text value'} x'424c4f42' -45678.6 394507}

# EVIDENCE-OF: R-60616-50251 If the default value of a column is an
# expression in parentheses, then the expression is evaluated once for
# each row inserted and the results used in the new row.
#
#   Test case 3.6.4 demonstrates that the expression is evaluated 
#   separately for each row if the INSERT is an "INSERT INTO ... SELECT ..."







|







950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
    d DEFAULT -45678.6,
    e DEFAULT 394507
  );
} {}
do_execsql_test e_createtable-3.6.2 {
  INSERT INTO t5 DEFAULT VALUES;
  SELECT quote(a), quote(b), quote(c), quote(d), quote(e) FROM t5;
} {NULL {'text value'} X'424C4F42' -45678.6 394507}

# EVIDENCE-OF: R-60616-50251 If the default value of a column is an
# expression in parentheses, then the expression is evaluated once for
# each row inserted and the results used in the new row.
#
#   Test case 3.6.4 demonstrates that the expression is evaluated 
#   separately for each row if the INSERT is an "INSERT INTO ... SELECT ..."
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
# default compile time value.
#
sqlite4_limit db SQLITE4_LIMIT_COLUMN [expr $::SQLITE4_MAX_COLUMN+2]
do_catchsql_test e_createtable-3.11.3 [subst {
  CREATE TABLE t11([columns [expr $::SQLITE4_MAX_COLUMN+1]]);
}] {1 {too many columns on t11}}

sqlite4_limit db SQLITE4_LIMIT_LENGTH 90013
do_execsql_test e_createtable-3.11.4 {
  CREATE TABLE t12(a, b, c);
  INSERT INTO t12 VALUES(randomblob(30000),randomblob(30000),randomblob(30000));
} {}
do_catchsql_test e_createtable-3.11.5 {
  INSERT INTO t12 VALUES(randomblob(30001),randomblob(30000),randomblob(30000));
} {1 {string or blob too big}}







|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
# default compile time value.
#
sqlite4_limit db SQLITE4_LIMIT_COLUMN [expr $::SQLITE4_MAX_COLUMN+2]
do_catchsql_test e_createtable-3.11.3 [subst {
  CREATE TABLE t11([columns [expr $::SQLITE4_MAX_COLUMN+1]]);
}] {1 {too many columns on t11}}

sqlite4_limit db SQLITE4_LIMIT_LENGTH 90010
do_execsql_test e_createtable-3.11.4 {
  CREATE TABLE t12(a, b, c);
  INSERT INTO t12 VALUES(randomblob(30000),randomblob(30000),randomblob(30000));
} {}
do_catchsql_test e_createtable-3.11.5 {
  INSERT INTO t12 VALUES(randomblob(30001),randomblob(30000),randomblob(30000));
} {1 {string or blob too big}}
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
  CREATE TABLE t2(x, y, PRIMARY KEY(x, y));
  INSERT INTO t2 VALUES(0,          'zero');
  INSERT INTO t2 VALUES(45.5,       'one');
  INSERT INTO t2 VALUES('brambles', 'two');
  INSERT INTO t2 VALUES(X'ABCDEF',  'three');
} {}

do_createtable_tests 4.3.1 -error { PRIMARY KEY must be unique%s } {
  1    "INSERT INTO t1 VALUES(0, 0)"                 {""}
  2    "INSERT INTO t1 VALUES(45.5, 'abc')"          {""}
  3    "INSERT INTO t1 VALUES(0.0, 'abc')"           {""}
  4    "INSERT INTO t1 VALUES('brambles', 'abc')"    {""}
  5    "INSERT INTO t1 VALUES(X'ABCDEF', 'abc')"     {""}

  6    "INSERT INTO t2 VALUES(0, 'zero')"            {""}
  7    "INSERT INTO t2 VALUES(45.5, 'one')"          {""}
  8    "INSERT INTO t2 VALUES(0.0, 'zero')"          {""}
  9    "INSERT INTO t2 VALUES('brambles', 'two')"    {""}
  10   "INSERT INTO t2 VALUES(X'ABCDEF', 'three')"   {""}
}
do_createtable_tests 4.3.2 {
  1    "INSERT INTO t1 VALUES(-1, 0)"                {}
  2    "INSERT INTO t1 VALUES(45.2, 'abc')"          {}
  3    "INSERT INTO t1 VALUES(0.01, 'abc')"          {}
  4    "INSERT INTO t1 VALUES('bramble', 'abc')"     {}
  5    "INSERT INTO t1 VALUES(X'ABCDEE', 'abc')"     {}

  6    "INSERT INTO t2 VALUES(0, 0)"                 {}
  7    "INSERT INTO t2 VALUES(45.5, 'abc')"          {}
  8    "INSERT INTO t2 VALUES(0.0, 'abc')"           {}
  9    "INSERT INTO t2 VALUES('brambles', 'abc')"    {}
  10   "INSERT INTO t2 VALUES(X'ABCDEF', 'abc')"     {}
}
do_createtable_tests 4.3.3 -error { PRIMARY KEY must be unique%s } {
  1    "UPDATE t1 SET x=0           WHERE y='two'"    {""}
  2    "UPDATE t1 SET x='brambles'  WHERE y='three'"  {""}
  3    "UPDATE t1 SET x=45.5        WHERE y='zero'"   {""}
  4    "UPDATE t1 SET x=X'ABCDEF'   WHERE y='one'"    {""}
  5    "UPDATE t1 SET x=0.0         WHERE y='three'"  {""}

  6    "UPDATE t2 SET x=0, y='zero' WHERE y='two'"    {""}
  7    "UPDATE t2 SET x='brambles', y='two' WHERE y='three'"  {""}

  8    "UPDATE t2 SET x=45.5, y='one' WHERE y='zero'" {""}
  9    "UPDATE t2 SET x=X'ABCDEF', y='three' WHERE y='one'" {""}

  10   "UPDATE t2 SET x=0.0, y='zero'        WHERE y='three'"  {""}

}



# src4 does not allow NULL values in primary key columns.

#
do_createtable_tests 4.4 -error { %s may not be NULL } {
  1    "INSERT INTO t1 VALUES(NULL, 0)"              {t1.x}
  2    "INSERT INTO t1 VALUES(NULL, 0)"              {t1.x}
  3    "INSERT INTO t1 VALUES(NULL, 0)"              {t1.x}

  4    "INSERT INTO t2 VALUES(NULL, 'zero')"         {t2.x}
  5    "INSERT INTO t2 VALUES(NULL, 'one')"          {t2.x}
  6    "INSERT INTO t2 VALUES(NULL, 'two')"          {t2.x}
  7    "INSERT INTO t2 VALUES(NULL, 'three')"        {t2.x}

  8    "INSERT INTO t2 VALUES(0, NULL)"              {t2.y}
  9    "INSERT INTO t2 VALUES(45.5, NULL)"           {t2.y}
  10   "INSERT INTO t2 VALUES(0.0, NULL)"            {t2.y}
  11   "INSERT INTO t2 VALUES('brambles', NULL)"     {t2.y}
  12   "INSERT INTO t2 VALUES(X'ABCDEF', NULL)"      {t2.y}

  13   "INSERT INTO t2 VALUES(NULL, NULL)"           {t2.x}
  14   "INSERT INTO t2 VALUES(NULL, NULL)"           {t2.x}
}








do_createtable_tests 4.5.1 {
  1    "SELECT count(*) FROM t1 WHERE x IS NULL"                   0
  2    "SELECT count(*) FROM t2 WHERE x IS NULL"                   0
  3    "SELECT count(*) FROM t2 WHERE y IS NULL"                   0
  4    "SELECT count(*) FROM t2 WHERE x IS NULL AND y IS NULL"     0
}
do_execsql_test 4.5.2 {
  CREATE TABLE t3(s, u INTEGER PRIMARY KEY, v);
  INSERT INTO t3 VALUES(1, NULL, 2);
  INSERT INTO t3 VALUES('x', NULL, 'y');
  SELECT u FROM t3;
} {1 2}
do_catchsql_test 4.5.3 {
  INSERT INTO t3 VALUES(2, 5, 3);
  UPDATE t3 SET u = NULL WHERE s = 2;
} {1 {t3.u may not be NULL}}

# EVIDENCE-OF: R-00227-21080 A UNIQUE constraint is similar to a PRIMARY
# KEY constraint, except that a single table may have any number of
# UNIQUE constraints.
#
drop_all_tables
do_createtable_tests 4.6 {







|
|
|
|
|
|

|
|
|
|
|














|
|
|
|
|
|

|
|
>
|
|
>
|
>



>
|
>

|
|
|
|

|
|
|
|

|
|
|
|
|

|
|


>
>
>
>
>
>
>

|
|
|
|










|







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
  CREATE TABLE t2(x, y, PRIMARY KEY(x, y));
  INSERT INTO t2 VALUES(0,          'zero');
  INSERT INTO t2 VALUES(45.5,       'one');
  INSERT INTO t2 VALUES('brambles', 'two');
  INSERT INTO t2 VALUES(X'ABCDEF',  'three');
} {}

do_createtable_tests 4.3.1 -error { %s not unique } {
  1    "INSERT INTO t1 VALUES(0, 0)"                 {"column x is"}
  2    "INSERT INTO t1 VALUES(45.5, 'abc')"          {"column x is"}
  3    "INSERT INTO t1 VALUES(0.0, 'abc')"           {"column x is"}
  4    "INSERT INTO t1 VALUES('brambles', 'abc')"    {"column x is"}
  5    "INSERT INTO t1 VALUES(X'ABCDEF', 'abc')"     {"column x is"}

  6    "INSERT INTO t2 VALUES(0, 'zero')"            {"columns x, y are"}
  7    "INSERT INTO t2 VALUES(45.5, 'one')"          {"columns x, y are"}
  8    "INSERT INTO t2 VALUES(0.0, 'zero')"          {"columns x, y are"}
  9    "INSERT INTO t2 VALUES('brambles', 'two')"    {"columns x, y are"}
  10   "INSERT INTO t2 VALUES(X'ABCDEF', 'three')"   {"columns x, y are"}
}
do_createtable_tests 4.3.2 {
  1    "INSERT INTO t1 VALUES(-1, 0)"                {}
  2    "INSERT INTO t1 VALUES(45.2, 'abc')"          {}
  3    "INSERT INTO t1 VALUES(0.01, 'abc')"          {}
  4    "INSERT INTO t1 VALUES('bramble', 'abc')"     {}
  5    "INSERT INTO t1 VALUES(X'ABCDEE', 'abc')"     {}

  6    "INSERT INTO t2 VALUES(0, 0)"                 {}
  7    "INSERT INTO t2 VALUES(45.5, 'abc')"          {}
  8    "INSERT INTO t2 VALUES(0.0, 'abc')"           {}
  9    "INSERT INTO t2 VALUES('brambles', 'abc')"    {}
  10   "INSERT INTO t2 VALUES(X'ABCDEF', 'abc')"     {}
}
do_createtable_tests 4.3.3 -error { %s not unique } {
  1    "UPDATE t1 SET x=0           WHERE y='two'"    {"column x is"}
  2    "UPDATE t1 SET x='brambles'  WHERE y='three'"  {"column x is"}
  3    "UPDATE t1 SET x=45.5        WHERE y='zero'"   {"column x is"}
  4    "UPDATE t1 SET x=X'ABCDEF'   WHERE y='one'"    {"column x is"}
  5    "UPDATE t1 SET x=0.0         WHERE y='three'"  {"column x is"}

  6    "UPDATE t2 SET x=0, y='zero' WHERE y='two'"    {"columns x, y are"}
  7    "UPDATE t2 SET x='brambles', y='two' WHERE y='three'"  
       {"columns x, y are"}
  8    "UPDATE t2 SET x=45.5, y='one' WHERE y='zero'" {"columns x, y are"}
  9    "UPDATE t2 SET x=X'ABCDEF', y='three' WHERE y='one'" 
       {"columns x, y are"}
  10   "UPDATE t2 SET x=0.0, y='zero'        WHERE y='three'"  
       {"columns x, y are"}
}


# EVIDENCE-OF: R-52572-02078 For the purposes of determining the
# uniqueness of primary key values, NULL values are considered distinct
# from all other values, including other NULLs.
#
do_createtable_tests 4.4 {
  1    "INSERT INTO t1 VALUES(NULL, 0)"              {}
  2    "INSERT INTO t1 VALUES(NULL, 0)"              {}
  3    "INSERT INTO t1 VALUES(NULL, 0)"              {}

  4    "INSERT INTO t2 VALUES(NULL, 'zero')"         {}
  5    "INSERT INTO t2 VALUES(NULL, 'one')"          {}
  6    "INSERT INTO t2 VALUES(NULL, 'two')"          {}
  7    "INSERT INTO t2 VALUES(NULL, 'three')"        {}

  8    "INSERT INTO t2 VALUES(0, NULL)"              {}
  9    "INSERT INTO t2 VALUES(45.5, NULL)"           {}
  10   "INSERT INTO t2 VALUES(0.0, NULL)"            {}
  11   "INSERT INTO t2 VALUES('brambles', NULL)"     {}
  12   "INSERT INTO t2 VALUES(X'ABCDEF', NULL)"      {}

  13   "INSERT INTO t2 VALUES(NULL, NULL)"           {}
  14   "INSERT INTO t2 VALUES(NULL, NULL)"           {}
}

# EVIDENCE-OF: R-61866-38053 Unless the column is an INTEGER PRIMARY KEY
# SQLite allows NULL values in a PRIMARY KEY column.
#
#     If the column is an integer primary key, attempting to insert a NULL
#     into the column triggers the auto-increment behaviour. Attempting
#     to use UPDATE to set an ipk column to a NULL value is an error.
#
do_createtable_tests 4.5.1 {
  1    "SELECT count(*) FROM t1 WHERE x IS NULL"                   3
  2    "SELECT count(*) FROM t2 WHERE x IS NULL"                   6
  3    "SELECT count(*) FROM t2 WHERE y IS NULL"                   7
  4    "SELECT count(*) FROM t2 WHERE x IS NULL AND y IS NULL"     2
}
do_execsql_test 4.5.2 {
  CREATE TABLE t3(s, u INTEGER PRIMARY KEY, v);
  INSERT INTO t3 VALUES(1, NULL, 2);
  INSERT INTO t3 VALUES('x', NULL, 'y');
  SELECT u FROM t3;
} {1 2}
do_catchsql_test 4.5.3 {
  INSERT INTO t3 VALUES(2, 5, 3);
  UPDATE t3 SET u = NULL WHERE s = 2;
} {1 {datatype mismatch}}

# EVIDENCE-OF: R-00227-21080 A UNIQUE constraint is similar to a PRIMARY
# KEY constraint, except that a single table may have any number of
# UNIQUE constraints.
#
drop_all_tables
do_createtable_tests 4.6 {
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
# EVIDENCE-OF: R-26983-26377 INTEGER PRIMARY KEY columns aside, both
# UNIQUE and PRIMARY KEY constraints are implemented by creating an
# index in the database (in the same way as a "CREATE UNIQUE INDEX"
# statement would).
do_createtable_tests 4.9 -repair drop_all_tables -query {
  SELECT count(*) FROM sqlite_master WHERE type='index'
} {
  1    "CREATE TABLE t1(a TEXT PRIMARY KEY, b)"              0
  2    "CREATE TABLE t1(a INTEGER PRIMARY KEY, b)"           0
  3    "CREATE TABLE t1(a TEXT UNIQUE, b)"                   1
  4    "CREATE TABLE t1(a PRIMARY KEY, b TEXT UNIQUE)"       1
  5    "CREATE TABLE t1(a PRIMARY KEY, b, c, UNIQUE(c, b))"  1
}

# EVIDENCE-OF: R-02252-33116 Such an index is used like any other index
# in the database to optimize queries.
#
do_execsql_test 4.10.0 {
  CREATE TABLE t1(a, b PRIMARY KEY);
  CREATE TABLE t2(a, b, c, UNIQUE(b, c));
}
do_createtable_tests 4.10 {
  1    "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 5" 
       {0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=?)}}

  2    "EXPLAIN QUERY PLAN SELECT * FROM t2 ORDER BY b, c"
       {0 0 0 {SCAN TABLE t2 USING INDEX sqlite_t2_unique1}}

  3    "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE b=10 AND c>10"
       {0 0 0 {SEARCH TABLE t2 USING INDEX sqlite_t2_unique1 (b=? AND c>?)}}
}

# EVIDENCE-OF: R-45493-35653 A CHECK constraint may be attached to a
# column definition or specified as a table constraint. In practice it
# makes no difference.
#
#   All the tests that deal with CHECK constraints below (4.11.* and 







|


|
|











|


|


|







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
# EVIDENCE-OF: R-26983-26377 INTEGER PRIMARY KEY columns aside, both
# UNIQUE and PRIMARY KEY constraints are implemented by creating an
# index in the database (in the same way as a "CREATE UNIQUE INDEX"
# statement would).
do_createtable_tests 4.9 -repair drop_all_tables -query {
  SELECT count(*) FROM sqlite_master WHERE type='index'
} {
  1    "CREATE TABLE t1(a TEXT PRIMARY KEY, b)"              1
  2    "CREATE TABLE t1(a INTEGER PRIMARY KEY, b)"           0
  3    "CREATE TABLE t1(a TEXT UNIQUE, b)"                   1
  4    "CREATE TABLE t1(a PRIMARY KEY, b TEXT UNIQUE)"       2
  5    "CREATE TABLE t1(a PRIMARY KEY, b, c, UNIQUE(c, b))"  2
}

# EVIDENCE-OF: R-02252-33116 Such an index is used like any other index
# in the database to optimize queries.
#
do_execsql_test 4.10.0 {
  CREATE TABLE t1(a, b PRIMARY KEY);
  CREATE TABLE t2(a, b, c, UNIQUE(b, c));
}
do_createtable_tests 4.10 {
  1    "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 5" 
       {0 0 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?) (~1 rows)}}

  2    "EXPLAIN QUERY PLAN SELECT * FROM t2 ORDER BY b, c"
       {0 0 0 {SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1 (~1000000 rows)}}

  3    "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE b=10 AND c>10"
       {0 0 0 {SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?) (~2 rows)}}
}

# EVIDENCE-OF: R-45493-35653 A CHECK constraint may be attached to a
# column definition or specified as a table constraint. In practice it
# makes no difference.
#
#   All the tests that deal with CHECK constraints below (4.11.* and 
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
  INSERT INTO t3_ig SELECT * FROM t3_ab;
  INSERT INTO t3_fa SELECT * FROM t3_ab;
  INSERT INTO t3_re SELECT * FROM t3_ab;
  INSERT INTO t3_xx SELECT * FROM t3_ab;
}

foreach {tn tbl res ac data} {
  1   t1_ab    {1 {PRIMARY KEY must be unique}} 0 {1 one 2 two 3 three}
  2   t1_ro    {1 {PRIMARY KEY must be unique}} 1 {1 one 2 two}
  3   t1_fa    {1 {PRIMARY KEY must be unique}} 0 {1 one 2 two 3 three 4 string}
  4   t1_ig    {0 {}} 0 {1 one 2 two 3 three 4 string 6 string}
  5   t1_re    {0 {}} 0 {1 one 2 two 3 string 4 string 6 string}
  6   t1_xx    {1 {PRIMARY KEY must be unique}} 0 {1 one 2 two 3 three}
} {
  catchsql COMMIT
  do_execsql_test  4.15.$tn.1 "BEGIN; INSERT INTO $tbl VALUES(3, 'three')"

  do_catchsql_test 4.15.$tn.2 " 
    INSERT INTO $tbl SELECT ((a%2)*a+3), 'string' FROM $tbl;
  " $res

  do_test e_createtable-4.15.$tn.3 { sqlite4_db_transaction_status db } [expr !$ac]
  do_execsql_test 4.15.$tn.4 "SELECT * FROM $tbl" $data
}
foreach {tn tbl res trans data} {
  1   t2_ab    {1 {t2_ab.b may not be NULL}} 1 {1 one 2 two 3 three}
  2   t2_ro    {1 {t2_ro.b may not be NULL}} 0 {1 one 2 two}
  3   t2_fa    {1 {t2_fa.b may not be NULL}} 1 {1 one 2 two 3 three 4 xx}
  4   t2_ig    {0 {}} 1 {1 one 2 two 3 three 4 xx 6 xx}
  5   t2_re    {1 {t2_re.b may not be NULL}} 1 {1 one 2 two 3 three}
  6   t2_xx    {1 {t2_xx.b may not be NULL}} 1 {1 one 2 two 3 three}
} {
  catchsql COMMIT
  do_execsql_test  4.16.$tn.1 "BEGIN; INSERT INTO $tbl VALUES(3, 'three')"

  do_catchsql_test 4.16.$tn.2 " 
    INSERT INTO $tbl SELECT a+3, CASE a WHEN 2 THEN NULL ELSE 'xx' END FROM $tbl
  " $res

  do_test e_createtable-4.16.$tn.3 { sqlite4_db_transaction_status db } $trans
  do_execsql_test 4.16.$tn.4 "SELECT * FROM $tbl" $data
}
foreach {tn tbl res trans data} {
  1   t3_ab    {1 {columns a, b are not unique}} 1 {1 one 2 two 3 three}
  2   t3_ro    {1 {columns a, b are not unique}} 0 {1 one 2 two}
  3   t3_fa    {1 {columns a, b are not unique}} 1 {1 one 2 two 3 three 4 three}
  4   t3_ig    {0 {}} 1 {1 one 2 two 3 three 4 three 6 three}
  5   t3_re    {0 {}} 1 {1 one 2 two 4 three 3 three 6 three}
  6   t3_xx    {1 {columns a, b are not unique}} 1 {1 one 2 two 3 three}
} {
  catchsql COMMIT
  do_execsql_test  4.17.$tn.1 "BEGIN; INSERT INTO $tbl VALUES(3, 'three')"

  do_catchsql_test 4.17.$tn.2 " 
    INSERT INTO $tbl SELECT ((a%2)*a+3), 'three' FROM $tbl
  " $res

  do_test e_createtable-4.17.$tn.3 { sqlite4_db_transaction_status db } $trans
  do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl" $data
}
catchsql COMMIT

# EVIDENCE-OF: R-12645-39772 Or, if a constraint definition does not
# include a conflict-clause or it is a CHECK constraint, the default
# conflict resolution algorithm is ABORT.







|
|
|

|
|








|


|
|
|
|
|
|
|








|


|
|
|
|
|
|
|








|







1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
  INSERT INTO t3_ig SELECT * FROM t3_ab;
  INSERT INTO t3_fa SELECT * FROM t3_ab;
  INSERT INTO t3_re SELECT * FROM t3_ab;
  INSERT INTO t3_xx SELECT * FROM t3_ab;
}

foreach {tn tbl res ac data} {
  1   t1_ab    {1 {column a is not unique}} 0 {1 one 2 two 3 three}
  2   t1_ro    {1 {column a is not unique}} 1 {1 one 2 two}
  3   t1_fa    {1 {column a is not unique}} 0 {1 one 2 two 3 three 4 string}
  4   t1_ig    {0 {}} 0 {1 one 2 two 3 three 4 string 6 string}
  5   t1_re    {0 {}} 0 {1 one 2 two 4 string 3 string 6 string}
  6   t1_xx    {1 {column a is not unique}} 0 {1 one 2 two 3 three}
} {
  catchsql COMMIT
  do_execsql_test  4.15.$tn.1 "BEGIN; INSERT INTO $tbl VALUES(3, 'three')"

  do_catchsql_test 4.15.$tn.2 " 
    INSERT INTO $tbl SELECT ((a%2)*a+3), 'string' FROM $tbl;
  " $res

  do_test e_createtable-4.15.$tn.3 { sqlite4_get_autocommit db } $ac
  do_execsql_test 4.15.$tn.4 "SELECT * FROM $tbl" $data
}
foreach {tn tbl res ac data} {
  1   t2_ab    {1 {t2_ab.b may not be NULL}} 0 {1 one 2 two 3 three}
  2   t2_ro    {1 {t2_ro.b may not be NULL}} 1 {1 one 2 two}
  3   t2_fa    {1 {t2_fa.b may not be NULL}} 0 {1 one 2 two 3 three 4 xx}
  4   t2_ig    {0 {}} 0 {1 one 2 two 3 three 4 xx 6 xx}
  5   t2_re    {1 {t2_re.b may not be NULL}} 0 {1 one 2 two 3 three}
  6   t2_xx    {1 {t2_xx.b may not be NULL}} 0 {1 one 2 two 3 three}
} {
  catchsql COMMIT
  do_execsql_test  4.16.$tn.1 "BEGIN; INSERT INTO $tbl VALUES(3, 'three')"

  do_catchsql_test 4.16.$tn.2 " 
    INSERT INTO $tbl SELECT a+3, CASE a WHEN 2 THEN NULL ELSE 'xx' END FROM $tbl
  " $res

  do_test e_createtable-4.16.$tn.3 { sqlite4_get_autocommit db } $ac
  do_execsql_test 4.16.$tn.4 "SELECT * FROM $tbl" $data
}
foreach {tn tbl res ac data} {
  1   t3_ab    {1 {columns a, b are not unique}} 0 {1 one 2 two 3 three}
  2   t3_ro    {1 {columns a, b are not unique}} 1 {1 one 2 two}
  3   t3_fa    {1 {columns a, b are not unique}} 0 {1 one 2 two 3 three 4 three}
  4   t3_ig    {0 {}} 0 {1 one 2 two 3 three 4 three 6 three}
  5   t3_re    {0 {}} 0 {1 one 2 two 4 three 3 three 6 three}
  6   t3_xx    {1 {columns a, b are not unique}} 0 {1 one 2 two 3 three}
} {
  catchsql COMMIT
  do_execsql_test  4.17.$tn.1 "BEGIN; INSERT INTO $tbl VALUES(3, 'three')"

  do_catchsql_test 4.17.$tn.2 " 
    INSERT INTO $tbl SELECT ((a%2)*a+3), 'three' FROM $tbl
  " $res

  do_test e_createtable-4.17.$tn.3 { sqlite4_get_autocommit db } $ac
  do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl" $data
}
catchsql COMMIT

# EVIDENCE-OF: R-12645-39772 Or, if a constraint definition does not
# include a conflict-clause or it is a CHECK constraint, the default
# conflict resolution algorithm is ABORT.
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
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
  INSERT INTO t4 VALUES(1, 2);
  INSERT INTO t4 VALUES(3, 4);
}
do_execsql_test  4.18.2 { BEGIN; INSERT INTO t4 VALUES(5, 6) }
do_catchsql_test 4.18.3 { 
  INSERT INTO t4 SELECT a+4, b+4 FROM t4
} {1 {constraint failed}}
do_test e_createtable-4.18.4 { sqlite4_db_transaction_status db } 1
do_execsql_test 4.18.5 { SELECT * FROM t4 } {1 2 3 4 5 6}

# EVIDENCE-OF: R-19114-56113 Different constraints within the same table
# may have different default conflict resolution algorithms.
#
do_execsql_test 4.19.0 {
  CREATE TABLE t5(a NOT NULL ON CONFLICT IGNORE, b NOT NULL ON CONFLICT ABORT);
}
do_catchsql_test 4.19.1 { INSERT INTO t5 VALUES(NULL, 'not null') } {0 {}}
do_execsql_test  4.19.2 { SELECT * FROM t5 } {}
do_catchsql_test 4.19.3 { INSERT INTO t5 VALUES('not null', NULL) } \
  {1 {t5.b may not be NULL}}
do_execsql_test  4.19.4 { SELECT * FROM t5 } {}






























































































# EVIDENCE-OF: R-41444-49665 Other integer type names like "INT" or
# "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary
# key column to behave as an ordinary table column with integer affinity
# and a unique index, not as an alias for the rowid.
#
do_execsql_test 5.4.1 {
  CREATE TABLE t6(pk INT primary key);
  CREATE TABLE t7(pk BIGINT primary key);
  CREATE TABLE t8(pk SHORT INTEGER primary key);
  CREATE TABLE t9(pk UNSIGNED INTEGER primary key);
} 





do_execsql_test 5.4.3 {
  INSERT INTO t6 VALUES('2.0');
  INSERT INTO t7 VALUES('2.0');
  INSERT INTO t8 VALUES('2.0');
  INSERT INTO t9 VALUES('2.0');
  SELECT typeof(pk), pk FROM t6;
  SELECT typeof(pk), pk FROM t7;
  SELECT typeof(pk), pk FROM t8;
  SELECT typeof(pk), pk FROM t9;
} {integer 2 integer 2 integer 2 integer 2}

do_catchsql_test 5.4.4.1 { 
  INSERT INTO t6 VALUES(2) 
} {1 {PRIMARY KEY must be unique}}
do_catchsql_test 5.4.4.2 { 
  INSERT INTO t7 VALUES(2) 
} {1 {PRIMARY KEY must be unique}}
do_catchsql_test 5.4.4.3 { 
  INSERT INTO t8 VALUES(2) 
} {1 {PRIMARY KEY must be unique}}
do_catchsql_test 5.4.4.4 { 
  INSERT INTO t9 VALUES(2) 






} {1 {PRIMARY KEY must be unique}}




























































































































































finish_test







|














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












>
>
>
>














|


|


|


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

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
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
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
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
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
  INSERT INTO t4 VALUES(1, 2);
  INSERT INTO t4 VALUES(3, 4);
}
do_execsql_test  4.18.2 { BEGIN; INSERT INTO t4 VALUES(5, 6) }
do_catchsql_test 4.18.3 { 
  INSERT INTO t4 SELECT a+4, b+4 FROM t4
} {1 {constraint failed}}
do_test e_createtable-4.18.4 { sqlite4_get_autocommit db } 0
do_execsql_test 4.18.5 { SELECT * FROM t4 } {1 2 3 4 5 6}

# EVIDENCE-OF: R-19114-56113 Different constraints within the same table
# may have different default conflict resolution algorithms.
#
do_execsql_test 4.19.0 {
  CREATE TABLE t5(a NOT NULL ON CONFLICT IGNORE, b NOT NULL ON CONFLICT ABORT);
}
do_catchsql_test 4.19.1 { INSERT INTO t5 VALUES(NULL, 'not null') } {0 {}}
do_execsql_test  4.19.2 { SELECT * FROM t5 } {}
do_catchsql_test 4.19.3 { INSERT INTO t5 VALUES('not null', NULL) } \
  {1 {t5.b may not be NULL}}
do_execsql_test  4.19.4 { SELECT * FROM t5 } {}

#------------------------------------------------------------------------
# Tests for INTEGER PRIMARY KEY and rowid related statements.
#

# EVIDENCE-OF: R-52584-04009 The rowid value can be accessed using one
# of the special case-independent names "rowid", "oid", or "_rowid_" in
# place of a column name.
#
drop_all_tables
do_execsql_test 5.1.0 {
  CREATE TABLE t1(x, y);
  INSERT INTO t1 VALUES('one', 'first');
  INSERT INTO t1 VALUES('two', 'second');
  INSERT INTO t1 VALUES('three', 'third');
}
do_createtable_tests 5.1 {
  1   "SELECT rowid FROM t1"        {1 2 3}
  2   "SELECT oid FROM t1"          {1 2 3}
  3   "SELECT _rowid_ FROM t1"      {1 2 3}
  4   "SELECT ROWID FROM t1"        {1 2 3}
  5   "SELECT OID FROM t1"          {1 2 3}
  6   "SELECT _ROWID_ FROM t1"      {1 2 3}
  7   "SELECT RoWiD FROM t1"        {1 2 3}
  8   "SELECT OiD FROM t1"          {1 2 3}
  9   "SELECT _RoWiD_ FROM t1"      {1 2 3}
}

# EVIDENCE-OF: R-26501-17306 If a table contains a user defined column
# named "rowid", "oid" or "_rowid_", then that name always refers the
# explicitly declared column and cannot be used to retrieve the integer
# rowid value.
#
do_execsql_test 5.2.0 {
  CREATE TABLE t2(oid, b);
  CREATE TABLE t3(a, _rowid_);
  CREATE TABLE t4(a, b, rowid);

  INSERT INTO t2 VALUES('one', 'two');
  INSERT INTO t2 VALUES('three', 'four');

  INSERT INTO t3 VALUES('five', 'six');
  INSERT INTO t3 VALUES('seven', 'eight');

  INSERT INTO t4 VALUES('nine', 'ten', 'eleven');
  INSERT INTO t4 VALUES('twelve', 'thirteen', 'fourteen');
}
do_createtable_tests 5.2 {
  1   "SELECT oid, rowid, _rowid_ FROM t2"   {one 1 1      three 2 2}
  2   "SELECT oid, rowid, _rowid_ FROM t3"   {1 1 six      2 2 eight} 
  3   "SELECT oid, rowid, _rowid_ FROM t4"   {1 eleven 1   2 fourteen 2}
}


# Argument $tbl is the name of a table in the database. Argument $col is
# the name of one of the tables columns. Return 1 if $col is an alias for
# the rowid, or 0 otherwise.
#
proc is_integer_primary_key {tbl col} {
  lindex [db eval [subst {
    DELETE FROM $tbl;
    INSERT INTO $tbl ($col) VALUES(0);
    SELECT (rowid==$col) FROM $tbl;
    DELETE FROM $tbl;
  }]] 0
}

# EVIDENCE-OF: R-53738-31673 With one exception, if a table has a
# primary key that consists of a single column, and the declared type of
# that column is "INTEGER" in any mixture of upper and lower case, then
# the column becomes an alias for the rowid.
#
# EVIDENCE-OF: R-45951-08347 if the declaration of a column with
# declared type "INTEGER" includes an "PRIMARY KEY DESC" clause, it does
# not become an alias for the rowid and is not classified as an integer
# primary key.
#
do_createtable_tests 5.3 -tclquery { 
  is_integer_primary_key t5 pk
} -repair {
  catchsql { DROP TABLE t5 }
} {
  1   "CREATE TABLE t5(pk integer primary key)"                         1
  2   "CREATE TABLE t5(pk integer, primary key(pk))"                    1
  3   "CREATE TABLE t5(pk integer, v integer, primary key(pk))"         1
  4   "CREATE TABLE t5(pk integer, v integer, primary key(pk, v))"      0
  5   "CREATE TABLE t5(pk int, v integer, primary key(pk, v))"          0
  6   "CREATE TABLE t5(pk int, v integer, primary key(pk))"             0
  7   "CREATE TABLE t5(pk int primary key, v integer)"                  0
  8   "CREATE TABLE t5(pk inTEger primary key)"                         1
  9   "CREATE TABLE t5(pk inteGEr, primary key(pk))"                    1
  10  "CREATE TABLE t5(pk INTEGER, v integer, primary key(pk))"         1
}

# EVIDENCE-OF: R-41444-49665 Other integer type names like "INT" or
# "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary
# key column to behave as an ordinary table column with integer affinity
# and a unique index, not as an alias for the rowid.
#
do_execsql_test 5.4.1 {
  CREATE TABLE t6(pk INT primary key);
  CREATE TABLE t7(pk BIGINT primary key);
  CREATE TABLE t8(pk SHORT INTEGER primary key);
  CREATE TABLE t9(pk UNSIGNED INTEGER primary key);
} 
do_test e_createtable-5.4.2.1 { is_integer_primary_key t6 pk } 0
do_test e_createtable-5.4.2.2 { is_integer_primary_key t7 pk } 0
do_test e_createtable-5.4.2.3 { is_integer_primary_key t8 pk } 0
do_test e_createtable-5.4.2.4 { is_integer_primary_key t9 pk } 0

do_execsql_test 5.4.3 {
  INSERT INTO t6 VALUES('2.0');
  INSERT INTO t7 VALUES('2.0');
  INSERT INTO t8 VALUES('2.0');
  INSERT INTO t9 VALUES('2.0');
  SELECT typeof(pk), pk FROM t6;
  SELECT typeof(pk), pk FROM t7;
  SELECT typeof(pk), pk FROM t8;
  SELECT typeof(pk), pk FROM t9;
} {integer 2 integer 2 integer 2 integer 2}

do_catchsql_test 5.4.4.1 { 
  INSERT INTO t6 VALUES(2) 
} {1 {column pk is not unique}}
do_catchsql_test 5.4.4.2 { 
  INSERT INTO t7 VALUES(2) 
} {1 {column pk is not unique}}
do_catchsql_test 5.4.4.3 { 
  INSERT INTO t8 VALUES(2) 
} {1 {column pk is not unique}}
do_catchsql_test 5.4.4.4 { 
  INSERT INTO t9 VALUES(2) 
} {1 {column pk is not unique}}

# EVIDENCE-OF: R-56094-57830 the following three table declarations all
# cause the column "x" to be an alias for the rowid (an integer primary
# key): CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z); CREATE TABLE
# t(x INTEGER, y, z, PRIMARY KEY(x ASC)); CREATE TABLE t(x INTEGER, y,
# z, PRIMARY KEY(x DESC));
#
# EVIDENCE-OF: R-20149-25884 the following declaration does not result
# in "x" being an alias for the rowid: CREATE TABLE t(x INTEGER PRIMARY
# KEY DESC, y, z);
#
do_createtable_tests 5 -tclquery { 
  is_integer_primary_key t x
} -repair {
  catchsql { DROP TABLE t }
} {
  5.1    "CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z)"      1
  5.2    "CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x ASC))"  1
  5.3    "CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x DESC))" 1
  6.1    "CREATE TABLE t(x INTEGER PRIMARY KEY DESC, y, z)"     0
}

# EVIDENCE-OF: R-03733-29734 Rowid values may be modified using an
# UPDATE statement in the same way as any other column value can, either
# using one of the built-in aliases ("rowid", "oid" or "_rowid_") or by
# using an alias created by an integer primary key.
#
do_execsql_test 5.7.0 {
  CREATE TABLE t10(a, b);
  INSERT INTO t10 VALUES('ten', 10);

  CREATE TABLE t11(a, b INTEGER PRIMARY KEY);
  INSERT INTO t11 VALUES('ten', 10);
}
do_createtable_tests 5.7.1 -query { 
  SELECT rowid, _rowid_, oid FROM t10;
} {
  1    "UPDATE t10 SET rowid = 5"   {5 5 5}
  2    "UPDATE t10 SET _rowid_ = 6" {6 6 6}
  3    "UPDATE t10 SET oid = 7"     {7 7 7}
}
do_createtable_tests 5.7.2 -query { 
  SELECT rowid, _rowid_, oid, b FROM t11;
} {
  1    "UPDATE t11 SET rowid = 5"   {5 5 5 5}
  2    "UPDATE t11 SET _rowid_ = 6" {6 6 6 6}
  3    "UPDATE t11 SET oid = 7"     {7 7 7 7}
  4    "UPDATE t11 SET b = 8"       {8 8 8 8}
}

# EVIDENCE-OF: R-58706-14229 Similarly, an INSERT statement may provide
# a value to use as the rowid for each row inserted.
#
do_createtable_tests 5.8.1 -query { 
  SELECT rowid, _rowid_, oid FROM t10;
} -repair { 
  execsql { DELETE FROM t10 } 
} {
  1    "INSERT INTO t10(oid) VALUES(15)"           {15 15 15}
  2    "INSERT INTO t10(rowid) VALUES(16)"         {16 16 16}
  3    "INSERT INTO t10(_rowid_) VALUES(17)"       {17 17 17}
  4    "INSERT INTO t10(a, b, oid) VALUES(1,2,3)"  {3 3 3}
}
do_createtable_tests 5.8.2 -query { 
  SELECT rowid, _rowid_, oid, b FROM t11;
} -repair { 
  execsql { DELETE FROM t11 } 
} {
  1    "INSERT INTO t11(oid) VALUES(15)"           {15 15 15 15}
  2    "INSERT INTO t11(rowid) VALUES(16)"         {16 16 16 16}
  3    "INSERT INTO t11(_rowid_) VALUES(17)"       {17 17 17 17}
  4    "INSERT INTO t11(a, b) VALUES(1,2)"         {2 2 2 2}
}

# EVIDENCE-OF: R-32326-44592 Unlike normal SQLite columns, an integer
# primary key or rowid column must contain integer values. Integer
# primary key or rowid columns are not able to hold floating point
# values, strings, BLOBs, or NULLs.
#
#     This is considered by the tests for the following 3 statements,
#     which show that:
#
#       1. Attempts to UPDATE a rowid column to a non-integer value fail,
#       2. Attempts to INSERT a real, string or blob value into a rowid 
#          column fail, and
#       3. Attempting to INSERT a NULL value into a rowid column causes the
#          system to automatically select an integer value to use.
#


# EVIDENCE-OF: R-64224-62578 If an UPDATE statement attempts to set an
# integer primary key or rowid column to a NULL or blob value, or to a
# string or real value that cannot be losslessly converted to an
# integer, a "datatype mismatch" error occurs and the statement is
# aborted.
#
drop_all_tables
do_execsql_test 5.9.0 {
  CREATE TABLE t12(x INTEGER PRIMARY KEY, y);
  INSERT INTO t12 VALUES(5, 'five');
}
do_createtable_tests 5.9.1 -query { SELECT typeof(x), x FROM t12 } {
  1   "UPDATE t12 SET x = 4"       {integer 4}
  2   "UPDATE t12 SET x = 10.0"    {integer 10}
  3   "UPDATE t12 SET x = '12.0'"  {integer 12}
  4   "UPDATE t12 SET x = '-15.0'" {integer -15}
}
do_createtable_tests 5.9.2 -error {
  datatype mismatch
} {
  1   "UPDATE t12 SET x = 4.1"         {}
  2   "UPDATE t12 SET x = 'hello'"     {}
  3   "UPDATE t12 SET x = NULL"        {}
  4   "UPDATE t12 SET x = X'ABCD'"     {}
  5   "UPDATE t12 SET x = X'3900'"     {}
  6   "UPDATE t12 SET x = X'39'"       {}
}

# EVIDENCE-OF: R-05734-13629 If an INSERT statement attempts to insert a
# blob value, or a string or real value that cannot be losslessly
# converted to an integer into an integer primary key or rowid column, a
# "datatype mismatch" error occurs and the statement is aborted.
#
do_execsql_test 5.10.0 { DELETE FROM t12 }
do_createtable_tests 5.10.1 -error { 
  datatype mismatch
} {
  1   "INSERT INTO t12(x) VALUES(4.1)"     {}
  2   "INSERT INTO t12(x) VALUES('hello')" {}
  3   "INSERT INTO t12(x) VALUES(X'ABCD')" {}
  4   "INSERT INTO t12(x) VALUES(X'3900')" {}
  5   "INSERT INTO t12(x) VALUES(X'39')"   {}
}
do_createtable_tests 5.10.2 -query { 
  SELECT typeof(x), x FROM t12 
} -repair {
  execsql { DELETE FROM t12 }
} {
  1   "INSERT INTO t12(x) VALUES(4)"       {integer 4}
  2   "INSERT INTO t12(x) VALUES(10.0)"    {integer 10}
  3   "INSERT INTO t12(x) VALUES('12.0')"  {integer 12}
  4   "INSERT INTO t12(x) VALUES('4e3')"   {integer 4000}
  5   "INSERT INTO t12(x) VALUES('-14.0')" {integer -14}
}

# EVIDENCE-OF: R-07986-46024 If an INSERT statement attempts to insert a
# NULL value into a rowid or integer primary key column, the system
# chooses an integer value to use as the rowid automatically.
#
do_execsql_test 5.11.0 { DELETE FROM t12 }
do_createtable_tests 5.11 -query { 
  SELECT typeof(x), x FROM t12 WHERE y IS (SELECT max(y) FROM t12)
} {
  1   "INSERT INTO t12 DEFAULT VALUES"                {integer 1}
  2   "INSERT INTO t12(y)   VALUES(5)"                {integer 2}
  3   "INSERT INTO t12(x,y) VALUES(NULL, 10)"         {integer 3}
  4   "INSERT INTO t12(x,y) SELECT NULL, 15 FROM t12" 
      {integer 4 integer 5 integer 6}
  5   "INSERT INTO t12(y) SELECT 20 FROM t12 LIMIT 3"
      {integer 7 integer 8 integer 9}
}

finish_test
Changes to test/e_delete.test.
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# top-level statement (by searching first the TEMP database, then the
# main database, then any other databases in the order they were
# attached).
#
do_execsql_test e_delete-2.3.0 {
  DROP TRIGGER aux.tr1;
  DROP TRIGGER main.tr1;
  DELETE FROM main.t8 WHERE rowid>1;
  DELETE FROM aux.t8 WHERE rowid>1;
  INSERT INTO aux.t9 VALUES(1, 2);
  INSERT INTO main.t7 VALUES(3, 4);
} {}
do_execsql_test e_delete-2.3.1 {
  SELECT count(*) FROM temp.t7 UNION ALL SELECT count(*) FROM main.t7 UNION ALL
  SELECT count(*) FROM aux.t7  UNION ALL SELECT count(*) FROM aux2.t7;








|
|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# top-level statement (by searching first the TEMP database, then the
# main database, then any other databases in the order they were
# attached).
#
do_execsql_test e_delete-2.3.0 {
  DROP TRIGGER aux.tr1;
  DROP TRIGGER main.tr1;
  DELETE FROM main.t8 WHERE oid>1;
  DELETE FROM aux.t8 WHERE oid>1;
  INSERT INTO aux.t9 VALUES(1, 2);
  INSERT INTO main.t7 VALUES(3, 4);
} {}
do_execsql_test e_delete-2.3.1 {
  SELECT count(*) FROM temp.t7 UNION ALL SELECT count(*) FROM main.t7 UNION ALL
  SELECT count(*) FROM aux.t7  UNION ALL SELECT count(*) FROM aux2.t7;

Changes to test/e_expr.test.
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
#   ::oplist         A list of all SQL operators supported by SQLite.
#
foreach {op opn} {
      ||   cat     *   mul       /  div       %     mod       +      add
      -    sub     <<  lshift    >> rshift    &     bitand    |      bitor
      <    less    <=  lesseq    >  more      >=    moreeq    =      eq1
      ==   eq2     <>  ne1       != ne2       IS    is        LIKE   like
      GLOB glob    AND and       OR or        REGEXP regexp
      {IS NOT} isnt
} {
  set ::opname($op) $opn
}
set oplist [list]
foreach {prec opl} {
  1   ||
  2   {* / %}
  3   {+ -}
  4   {<< >> & |}
  5   {< <= > >=}
  6   {= == != <> IS {IS NOT} LIKE GLOB REGEXP}
  7   AND
  8   OR
} {
  foreach op $opl { 
    set ::opprec($op) $prec 
    lappend oplist $op
  }







|











|







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
#   ::oplist         A list of all SQL operators supported by SQLite.
#
foreach {op opn} {
      ||   cat     *   mul       /  div       %     mod       +      add
      -    sub     <<  lshift    >> rshift    &     bitand    |      bitor
      <    less    <=  lesseq    >  more      >=    moreeq    =      eq1
      ==   eq2     <>  ne1       != ne2       IS    is        LIKE   like
      GLOB glob    AND and       OR or        MATCH match     REGEXP regexp
      {IS NOT} isnt
} {
  set ::opname($op) $opn
}
set oplist [list]
foreach {prec opl} {
  1   ||
  2   {* / %}
  3   {+ -}
  4   {<< >> & |}
  5   {< <= > >=}
  6   {= == != <> IS {IS NOT} LIKE GLOB MATCH REGEXP}
  7   AND
  8   OR
} {
  foreach op $opl { 
    set ::opprec($op) $prec 
    lappend oplist $op
  }
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# the operand.
#
foreach {tn literal type} {
  1     'helloworld'   text
  2     45             integer
  3     45.2           real
  4     45.0           real
  5     x'abcdef'      blob
  6     NULL           null
} {
  set sql " SELECT quote( + $literal ), typeof( + $literal) "
  do_execsql_test e_expr-3.$tn $sql [list $literal $type]
}

#-------------------------------------------------------------------------







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# the operand.
#
foreach {tn literal type} {
  1     'helloworld'   text
  2     45             integer
  3     45.2           real
  4     45.0           real
  5     X'ABCDEF'      blob
  6     NULL           null
} {
  set sql " SELECT quote( + $literal ), typeof( + $literal) "
  do_execsql_test e_expr-3.$tn $sql [list $literal $type]
}

#-------------------------------------------------------------------------
733
734
735
736
737
738
739


740
741
742
743
744
745
746
 
  54 "EXPR1 LIKE EXPR2"
  55 "EXPR1 LIKE EXPR2 ESCAPE EXPR"
  56 "EXPR1 GLOB EXPR2"
  57 "EXPR1 GLOB EXPR2 ESCAPE EXPR"
  58 "EXPR1 REGEXP EXPR2"
  59 "EXPR1 REGEXP EXPR2 ESCAPE EXPR"


  62 "EXPR1 NOT LIKE EXPR2"
  63 "EXPR1 NOT LIKE EXPR2 ESCAPE EXPR"
  64 "EXPR1 NOT GLOB EXPR2"
  65 "EXPR1 NOT GLOB EXPR2 ESCAPE EXPR"
  66 "EXPR1 NOT REGEXP EXPR2"
  67 "EXPR1 NOT REGEXP EXPR2 ESCAPE EXPR"
  68 "EXPR1 NOT MATCH EXPR2"







>
>







733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
 
  54 "EXPR1 LIKE EXPR2"
  55 "EXPR1 LIKE EXPR2 ESCAPE EXPR"
  56 "EXPR1 GLOB EXPR2"
  57 "EXPR1 GLOB EXPR2 ESCAPE EXPR"
  58 "EXPR1 REGEXP EXPR2"
  59 "EXPR1 REGEXP EXPR2 ESCAPE EXPR"
  60 "EXPR1 MATCH EXPR2"
  61 "EXPR1 MATCH EXPR2 ESCAPE EXPR"
  62 "EXPR1 NOT LIKE EXPR2"
  63 "EXPR1 NOT LIKE EXPR2 ESCAPE EXPR"
  64 "EXPR1 NOT GLOB EXPR2"
  65 "EXPR1 NOT GLOB EXPR2 ESCAPE EXPR"
  66 "EXPR1 NOT REGEXP EXPR2"
  67 "EXPR1 NOT REGEXP EXPR2 ESCAPE EXPR"
  68 "EXPR1 NOT MATCH EXPR2"
1087
1088
1089
1090
1091
1092
1093





























1094
1095
1096
1097
1098
1099
1100
set ::regexpargs [list]
do_execsql_test e_expr-18.2.1 { SELECT 'abc' REGEXP 'def' } 1
do_test         e_expr-18.2.2 { set regexpargs } {def abc}
set ::regexpargs [list]
do_execsql_test e_expr-18.2.3 { SELECT 'X' NOT REGEXP 'Y' } 0
do_test         e_expr-18.2.4 { set regexpargs } {Y X}
sqlite4 db test.db






























#-------------------------------------------------------------------------
# Test cases for the testable statements related to the CASE expression.
#
# EVIDENCE-OF: R-15199-61389 There are two basic forms of the CASE
# expression: those with a base expression and those without.
#







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







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
set ::regexpargs [list]
do_execsql_test e_expr-18.2.1 { SELECT 'abc' REGEXP 'def' } 1
do_test         e_expr-18.2.2 { set regexpargs } {def abc}
set ::regexpargs [list]
do_execsql_test e_expr-18.2.3 { SELECT 'X' NOT REGEXP 'Y' } 0
do_test         e_expr-18.2.4 { set regexpargs } {Y X}
sqlite4 db test.db

# EVIDENCE-OF: R-42037-37826 The default match() function implementation
# raises an exception and is not really useful for anything.
#
do_catchsql_test e_expr-19.1.1 { 
  SELECT 'abc' MATCH 'def' 
} {1 {unable to use function MATCH in the requested context}}
do_catchsql_test e_expr-19.1.2 { 
  SELECT match('abc', 'def')
} {1 {unable to use function MATCH in the requested context}}

# EVIDENCE-OF: R-37916-47407 The MATCH operator is a special syntax for
# the match() application-defined function.
#
# EVIDENCE-OF: R-06021-09373 But extensions can override the match()
# function with more helpful logic.
#
proc matchfunc {args} {
  eval lappend ::matchargs $args
  return 1
}
db func match -argcount 2 matchfunc
set ::matchargs [list]
do_execsql_test e_expr-19.2.1 { SELECT 'abc' MATCH 'def' } 1
do_test         e_expr-19.2.2 { set matchargs } {def abc}
set ::matchargs [list]
do_execsql_test e_expr-19.2.3 { SELECT 'X' NOT MATCH 'Y' } 0
do_test         e_expr-19.2.4 { set matchargs } {Y X}
sqlite4 db test.db

#-------------------------------------------------------------------------
# Test cases for the testable statements related to the CASE expression.
#
# EVIDENCE-OF: R-15199-61389 There are two basic forms of the CASE
# expression: those with a base expression and those without.
#
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
  SELECT CASE 'AbC' WHEN 'abc' THEN 'A' WHEN a THEN 'B' END FROM t1
} {B}
do_execsql_test e_expr-23.1.4 {
  SELECT CASE a WHEN b THEN 'A' ELSE 'B' END FROM t1
} {B}
do_execsql_test e_expr-23.1.5 {
  SELECT CASE b WHEN a THEN 'A' ELSE 'B' END FROM t1
} {B}
do_execsql_test e_expr-23.1.6 {
  SELECT CASE 55 WHEN '55' THEN 'A' ELSE 'B' END
} {B}
do_execsql_test e_expr-23.1.7 {
  SELECT CASE c WHEN '55' THEN 'A' ELSE 'B' END FROM t1
} {A}
do_execsql_test e_expr-23.1.8 {







|







1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
  SELECT CASE 'AbC' WHEN 'abc' THEN 'A' WHEN a THEN 'B' END FROM t1
} {B}
do_execsql_test e_expr-23.1.4 {
  SELECT CASE a WHEN b THEN 'A' ELSE 'B' END FROM t1
} {B}
do_execsql_test e_expr-23.1.5 {
  SELECT CASE b WHEN a THEN 'A' ELSE 'B' END FROM t1
} {A}
do_execsql_test e_expr-23.1.6 {
  SELECT CASE 55 WHEN '55' THEN 'A' ELSE 'B' END
} {B}
do_execsql_test e_expr-23.1.7 {
  SELECT CASE c WHEN '55' THEN 'A' ELSE 'B' END FROM t1
} {A}
do_execsql_test e_expr-23.1.8 {
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
do_expr_test e_expr-27.3.2 { CAST('def' AS shobblob_x) } blob def
do_expr_test e_expr-27.3.3 { CAST('ghi' AS abbLOb10)   } blob ghi

# EVIDENCE-OF: R-22956-37754 Casting to a BLOB consists of first casting
# the value to TEXT in the encoding of the database connection, then
# interpreting the resulting byte sequence as a BLOB instead of as TEXT.
#
do_qexpr_test e_expr-27.4.1 { CAST('ghi' AS blob) } x'676869'
do_qexpr_test e_expr-27.4.2 { CAST(456 AS blob) }   x'343536'
do_qexpr_test e_expr-27.4.3 { CAST(1.78 AS blob) }  x'312e3738'
rename db db2
sqlite4 db :memory:
ifcapable {utf16} {
db eval { PRAGMA encoding = 'utf-16le' }
do_qexpr_test e_expr-27.4.4 { CAST('ghi' AS blob) } x'670068006900'
do_qexpr_test e_expr-27.4.5 { CAST(456 AS blob) }   x'340035003600'
do_qexpr_test e_expr-27.4.6 { CAST(1.78 AS blob) }  x'31002e0037003800'
}
db close
sqlite4 db :memory:
db eval { PRAGMA encoding = 'utf-16be' }
ifcapable {utf16} {
do_qexpr_test e_expr-27.4.7 { CAST('ghi' AS blob) } x'006700680069'
do_qexpr_test e_expr-27.4.8 { CAST(456 AS blob) }   x'003400350036'
do_qexpr_test e_expr-27.4.9 { CAST(1.78 AS blob) }  x'0031002e00370038'
}
db close
rename db2 db

# EVIDENCE-OF: R-04207-37981 To cast a BLOB value to TEXT, the sequence
# of bytes that make up the BLOB is interpreted as text encoded using
# the database encoding.







|
|
|




|
|
|





|
|
|







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
do_expr_test e_expr-27.3.2 { CAST('def' AS shobblob_x) } blob def
do_expr_test e_expr-27.3.3 { CAST('ghi' AS abbLOb10)   } blob ghi

# EVIDENCE-OF: R-22956-37754 Casting to a BLOB consists of first casting
# the value to TEXT in the encoding of the database connection, then
# interpreting the resulting byte sequence as a BLOB instead of as TEXT.
#
do_qexpr_test e_expr-27.4.1 { CAST('ghi' AS blob) } X'676869'
do_qexpr_test e_expr-27.4.2 { CAST(456 AS blob) }   X'343536'
do_qexpr_test e_expr-27.4.3 { CAST(1.78 AS blob) }  X'312E3738'
rename db db2
sqlite4 db :memory:
ifcapable {utf16} {
db eval { PRAGMA encoding = 'utf-16le' }
do_qexpr_test e_expr-27.4.4 { CAST('ghi' AS blob) } X'670068006900'
do_qexpr_test e_expr-27.4.5 { CAST(456 AS blob) }   X'340035003600'
do_qexpr_test e_expr-27.4.6 { CAST(1.78 AS blob) }  X'31002E0037003800'
}
db close
sqlite4 db :memory:
db eval { PRAGMA encoding = 'utf-16be' }
ifcapable {utf16} {
do_qexpr_test e_expr-27.4.7 { CAST('ghi' AS blob) } X'006700680069'
do_qexpr_test e_expr-27.4.8 { CAST(456 AS blob) }   X'003400350036'
do_qexpr_test e_expr-27.4.9 { CAST(1.78 AS blob) }  X'0031002E00370038'
}
db close
rename db2 db

# EVIDENCE-OF: R-04207-37981 To cast a BLOB value to TEXT, the sequence
# of bytes that make up the BLOB is interpreted as text encoded using
# the database encoding.
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
# resulting TEXT uses the encoding of the database connection.
#
do_expr_test e_expr-28.2.1 { CAST (1 AS text)   }     text 1
do_expr_test e_expr-28.2.2 { CAST (45 AS text)  }     text 45
do_expr_test e_expr-28.2.3 { CAST (-45 AS text) }     text -45
do_expr_test e_expr-28.2.4 { CAST (8.8 AS text)    }  text 8.8
do_expr_test e_expr-28.2.5 { CAST (2.3e+5 AS text) }  text 230000.0
do_expr_test e_expr-28.2.6 { CAST (-2.3e-5 AS text) } text -0.000023
do_expr_test e_expr-28.2.7 { CAST (0.0 AS text) }     text 0.0
do_expr_test e_expr-28.2.8 { CAST (0 AS text) }       text 0

# EVIDENCE-OF: R-26346-36443 When casting a BLOB value to a REAL, the
# value is first converted to TEXT.
#
do_expr_test e_expr-29.1.1 { CAST (X'312E3233' AS REAL) } real 1.23
do_expr_test e_expr-29.1.2 { CAST (X'3233302E30' AS REAL) } real 230.0
do_expr_test e_expr-29.1.3 { CAST (X'2D392E3837' AS REAL) } real -9.87







|

|







1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
# resulting TEXT uses the encoding of the database connection.
#
do_expr_test e_expr-28.2.1 { CAST (1 AS text)   }     text 1
do_expr_test e_expr-28.2.2 { CAST (45 AS text)  }     text 45
do_expr_test e_expr-28.2.3 { CAST (-45 AS text) }     text -45
do_expr_test e_expr-28.2.4 { CAST (8.8 AS text)    }  text 8.8
do_expr_test e_expr-28.2.5 { CAST (2.3e+5 AS text) }  text 230000.0
do_expr_test e_expr-28.2.6 { CAST (-2.3e-5 AS text) } text -2.3e-05
do_expr_test e_expr-28.2.7 { CAST (0.0 AS text) }     text 0.0
do_expr_test e_expr-28.2.7 { CAST (0 AS text) }       text 0

# EVIDENCE-OF: R-26346-36443 When casting a BLOB value to a REAL, the
# value is first converted to TEXT.
#
do_expr_test e_expr-29.1.1 { CAST (X'312E3233' AS REAL) } real 1.23
do_expr_test e_expr-29.1.2 { CAST (X'3233302E30' AS REAL) } real 230.0
do_expr_test e_expr-29.1.3 { CAST (X'2D392E3837' AS REAL) } real -9.87
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0

# EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as
# an INTEGER then the result of the cast is the largest negative
# integer: -9223372036854775808.
#
do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807
do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808
do_expr_test e_expr-31.2.3 { 
  CAST(-9223372036854775809.0 AS INT)
} integer -9223372036854775808
do_expr_test e_expr-31.2.4 { 
  CAST(9223372036854775809.0 AS INT)
} integer 9223372036854775807


# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC
# first does a forced conversion into REAL but then further converts the
# result into INTEGER if and only if the conversion from REAL to INTEGER
# is lossless and reversible.
#







|






|







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0

# EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as
# an INTEGER then the result of the cast is the largest negative
# integer: -9223372036854775808.
#
do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer -9223372036854775808
do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808
do_expr_test e_expr-31.2.3 { 
  CAST(-9223372036854775809.0 AS INT)
} integer -9223372036854775808
do_expr_test e_expr-31.2.4 { 
  CAST(9223372036854775809.0 AS INT)
} integer -9223372036854775808


# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC
# first does a forced conversion into REAL but then further converts the
# result into INTEGER if and only if the conversion from REAL to INTEGER
# is lossless and reversible.
#
Changes to test/e_fkey.test.
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
}

ifcapable !foreignkey||!trigger { finish_test ; return }
reset_db


#-------------------------------------------------------------------------

# Update for src4: foreign-keys are on by default.







#
drop_all_tables
do_test e_fkey-4.1 {
  execsql {
    CREATE TABLE p(i PRIMARY KEY);
    CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
    INSERT INTO p VALUES('hello');
    INSERT INTO c VALUES('hello');
    UPDATE p SET i = 'world';
    SELECT * FROM c;
  } 
} {world}
do_test e_fkey-4.2 {
  execsql {
    DELETE FROM c;
    DELETE FROM p;
    PRAGMA foreign_keys = ON;
    INSERT INTO p VALUES('hello');
    INSERT INTO c VALUES('hello');







>
|
>
>
>
>
>
>
>











|







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
}

ifcapable !foreignkey||!trigger { finish_test ; return }
reset_db


#-------------------------------------------------------------------------
# EVIDENCE-OF: R-07280-60510 Assuming the library is compiled with
# foreign key constraints enabled, it must still be enabled by the
# application at runtime, using the PRAGMA foreign_keys command.
#
# This also tests that foreign key constraints are disabled by default.
#
# EVIDENCE-OF: R-59578-04990 Foreign key constraints are disabled by
# default (for backwards compatibility), so must be enabled separately
# for each database connection separately.
#
drop_all_tables
do_test e_fkey-4.1 {
  execsql {
    CREATE TABLE p(i PRIMARY KEY);
    CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
    INSERT INTO p VALUES('hello');
    INSERT INTO c VALUES('hello');
    UPDATE p SET i = 'world';
    SELECT * FROM c;
  } 
} {hello}
do_test e_fkey-4.2 {
  execsql {
    DELETE FROM c;
    DELETE FROM p;
    PRAGMA foreign_keys = ON;
    INSERT INTO p VALUES('hello');
    INSERT INTO c VALUES('hello');
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# This also tests the example code in section 2 of foreignkeys.in.
#
# EVIDENCE-OF: R-11255-19907
# 
reset_db
do_test e_fkey-5.1 {
  execsql { PRAGMA foreign_keys }
} {1}
do_test e_fkey-5.2 {
  execsql { 
    PRAGMA foreign_keys = ON;
    PRAGMA foreign_keys;
  }
} {1}
do_test e_fkey-5.3 {







|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# This also tests the example code in section 2 of foreignkeys.in.
#
# EVIDENCE-OF: R-11255-19907
# 
reset_db
do_test e_fkey-5.1 {
  execsql { PRAGMA foreign_keys }
} {0}
do_test e_fkey-5.2 {
  execsql { 
    PRAGMA foreign_keys = ON;
    PRAGMA foreign_keys;
  }
} {1}
do_test e_fkey-5.3 {
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
    UPDATE t1 SET a = 'ONE';
  }
} {}
do_test e_fkey-16.3 {
  catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 }
} {1 {foreign key constraint failed}}
do_test e_fkey-16.4 {
  catchsql { DELETE FROM t1 WHERE a = 'oNe' }
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# Specifically, test that when comparing child and parent key values the
# affinity of the parent key column is applied to the child key value
# before the comparison takes place.
#







|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
    UPDATE t1 SET a = 'ONE';
  }
} {}
do_test e_fkey-16.3 {
  catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 }
} {1 {foreign key constraint failed}}
do_test e_fkey-16.4 {
  catchsql { DELETE FROM t1 WHERE rowid = 1 }
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# Specifically, test that when comparing child and parent key values the
# affinity of the parent key column is applied to the child key value
# before the comparison takes place.
#
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
    SELECT b, typeof(b) FROM t2;
  }
} {2.0 text}
do_test e_fkey-17.3 {
  execsql { SELECT typeof(a) FROM t1 }
} {integer integer text}
do_test e_fkey-17.4 {
  catchsql { DELETE FROM t1 WHERE a = 2 }
} {1 {foreign key constraint failed}}

###########################################################################
### SECTION 3: Required and Suggested Database Indexes
###########################################################################

#-------------------------------------------------------------------------







|







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    SELECT b, typeof(b) FROM t2;
  }
} {2.0 text}
do_test e_fkey-17.3 {
  execsql { SELECT typeof(a) FROM t1 }
} {integer integer text}
do_test e_fkey-17.4 {
  catchsql { DELETE FROM t1 WHERE rowid = 2 }
} {1 {foreign key constraint failed}}

###########################################################################
### SECTION 3: Required and Suggested Database Indexes
###########################################################################

#-------------------------------------------------------------------------
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
  }
} {}
do_execsql_test e_fkey-25.2 {
  PRAGMA foreign_keys = OFF;
  EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
} {
  0 0 0 {SCAN TABLE artist} 
  0 0 0 {SCAN TABLE track}
}
do_execsql_test e_fkey-25.3 {
  PRAGMA foreign_keys = ON;
  EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
} {
  0 0 0 {SCAN TABLE artist}
  0 0 0 {SCAN TABLE track}
}
do_test e_fkey-25.4 {
  execsql {
    INSERT INTO artist VALUES(5, 'artist 5');
    INSERT INTO artist VALUES(6, 'artist 6');
    INSERT INTO artist VALUES(7, 'artist 7');
    INSERT INTO track VALUES(1, 'track 1', 5);







|
|





|
|







969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
  }
} {}
do_execsql_test e_fkey-25.2 {
  PRAGMA foreign_keys = OFF;
  EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
} {
  0 0 0 {SCAN TABLE artist (~1000000 rows)} 
  0 0 0 {SCAN TABLE track (~100000 rows)}
}
do_execsql_test e_fkey-25.3 {
  PRAGMA foreign_keys = ON;
  EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
} {
  0 0 0 {SCAN TABLE artist (~1000000 rows)} 
  0 0 0 {SCAN TABLE track (~100000 rows)}
}
do_test e_fkey-25.4 {
  execsql {
    INSERT INTO artist VALUES(5, 'artist 5');
    INSERT INTO artist VALUES(6, 'artist 6');
    INSERT INTO artist VALUES(7, 'artist 7');
    INSERT INTO track VALUES(1, 'track 1', 5);
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
} {}
do_test e_fkey-27.2 {
  eqp { INSERT INTO artist VALUES(?, ?) }
} {}
do_execsql_test e_fkey-27.3 {
  EXPLAIN QUERY PLAN UPDATE artist SET artistid = ?, artistname = ?
} {
  0 0 0 {SCAN TABLE artist}
  0 0 0 {SEARCH TABLE track USING INDEX trackindex (trackartist=?)} 
  0 0 0 {SEARCH TABLE track USING INDEX trackindex (trackartist=?)}
}
do_execsql_test e_fkey-27.4 {
  EXPLAIN QUERY PLAN DELETE FROM artist
} {
  0 0 0 {SCAN TABLE artist} 
  0 0 0 {SEARCH TABLE track USING INDEX trackindex (trackartist=?)}
}


###########################################################################
### SECTION 4.1: Composite Foreign Key Constraints
###########################################################################








|
|
|




|
|







1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
} {}
do_test e_fkey-27.2 {
  eqp { INSERT INTO artist VALUES(?, ?) }
} {}
do_execsql_test e_fkey-27.3 {
  EXPLAIN QUERY PLAN UPDATE artist SET artistid = ?, artistname = ?
} {
  0 0 0 {SCAN TABLE artist (~1000000 rows)} 
  0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)} 
  0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)}
}
do_execsql_test e_fkey-27.4 {
  EXPLAIN QUERY PLAN DELETE FROM artist
} {
  0 0 0 {SCAN TABLE artist (~1000000 rows)} 
  0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)}
}


###########################################################################
### SECTION 4.1: Composite Foreign Key Constraints
###########################################################################

2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
    INSERT INTO pA VALUES(X'1234');
    INSERT INTO cA VALUES(X'ABCD');
    INSERT INTO cB VALUES(X'1234');
  }
} {}
do_test e_fkey-44.2 {
  execsql {
    DELETE FROM pA WHERE x = x'abcd';
    SELECT quote(x) FROM pA;
  }
} {x'1234'}
do_test e_fkey-44.3 {
  execsql {
    SELECT quote(c) FROM cA;
  }
} {NULL}
do_test e_fkey-44.4 {
  execsql {
    UPDATE pA SET x = X'8765' WHERE x = X'1234';
    SELECT quote(x) FROM pA;
  }
} {x'8765'}
do_test e_fkey-44.5 {
  execsql { SELECT quote(c) FROM cB }
} {NULL}

#-------------------------------------------------------------------------
# Test SET DEFAULT actions.
#
# EVIDENCE-OF: R-43054-54832 The "SET DEFAULT" actions are similar to
# "SET NULL", except that each of the child key columns is set to
# contain the columns default value instead of NULL.
#
drop_all_tables
do_test e_fkey-45.1 {
  execsql {
    CREATE TABLE pA(x PRIMARY KEY);
    CREATE TABLE cA(c DEFAULT X'0000' REFERENCES pA ON DELETE SET DEFAULT);
    CREATE TABLE cB(c DEFAULT X'9999' REFERENCES pA ON UPDATE SET DEFAULT);

    INSERT INTO pA(x) VALUES(X'0000');
    INSERT INTO pA(x) VALUES(X'9999');
    INSERT INTO pA(x) VALUES(X'ABCD');
    INSERT INTO pA(x) VALUES(X'1234');

    INSERT INTO cA VALUES(X'ABCD');
    INSERT INTO cB VALUES(X'1234');
  }
} {}
do_test e_fkey-45.2 {
  execsql {
    DELETE FROM pA WHERE x = X'ABCD';
    SELECT quote(x) FROM pA;
  }
} {x'0000' x'1234' x'9999'}
do_test e_fkey-45.3 {
  execsql { SELECT quote(c) FROM cA }
} {x'0000'}
do_test e_fkey-45.4 {
  execsql {
    UPDATE pA SET x = X'8765' WHERE x = X'1234';
    SELECT quote(x) FROM pA;
  }
} {x'0000' x'8765' x'9999'}
do_test e_fkey-45.5 {
  execsql { SELECT quote(c) FROM cB }
} {x'9999'}

#-------------------------------------------------------------------------
# Test ON DELETE CASCADE actions.
#
# EVIDENCE-OF: R-61376-57267 A "CASCADE" action propagates the delete or
# update operation on the parent key to each dependent child key.
#







|


|







|


|


















|
|
|
|







|


|


|


|


|


|







2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
    INSERT INTO pA VALUES(X'1234');
    INSERT INTO cA VALUES(X'ABCD');
    INSERT INTO cB VALUES(X'1234');
  }
} {}
do_test e_fkey-44.2 {
  execsql {
    DELETE FROM pA WHERE rowid = 1;
    SELECT quote(x) FROM pA;
  }
} {X'1234'}
do_test e_fkey-44.3 {
  execsql {
    SELECT quote(c) FROM cA;
  }
} {NULL}
do_test e_fkey-44.4 {
  execsql {
    UPDATE pA SET x = X'8765' WHERE rowid = 2;
    SELECT quote(x) FROM pA;
  }
} {X'8765'}
do_test e_fkey-44.5 {
  execsql { SELECT quote(c) FROM cB }
} {NULL}

#-------------------------------------------------------------------------
# Test SET DEFAULT actions.
#
# EVIDENCE-OF: R-43054-54832 The "SET DEFAULT" actions are similar to
# "SET NULL", except that each of the child key columns is set to
# contain the columns default value instead of NULL.
#
drop_all_tables
do_test e_fkey-45.1 {
  execsql {
    CREATE TABLE pA(x PRIMARY KEY);
    CREATE TABLE cA(c DEFAULT X'0000' REFERENCES pA ON DELETE SET DEFAULT);
    CREATE TABLE cB(c DEFAULT X'9999' REFERENCES pA ON UPDATE SET DEFAULT);

    INSERT INTO pA(rowid, x) VALUES(1, X'0000');
    INSERT INTO pA(rowid, x) VALUES(2, X'9999');
    INSERT INTO pA(rowid, x) VALUES(3, X'ABCD');
    INSERT INTO pA(rowid, x) VALUES(4, X'1234');

    INSERT INTO cA VALUES(X'ABCD');
    INSERT INTO cB VALUES(X'1234');
  }
} {}
do_test e_fkey-45.2 {
  execsql {
    DELETE FROM pA WHERE rowid = 3;
    SELECT quote(x) FROM pA;
  }
} {X'0000' X'9999' X'1234'}
do_test e_fkey-45.3 {
  execsql { SELECT quote(c) FROM cA }
} {X'0000'}
do_test e_fkey-45.4 {
  execsql {
    UPDATE pA SET x = X'8765' WHERE rowid = 4;
    SELECT quote(x) FROM pA;
  }
} {X'0000' X'9999' X'8765'}
do_test e_fkey-45.5 {
  execsql { SELECT quote(c) FROM cB }
} {X'9999'}

#-------------------------------------------------------------------------
# Test ON DELETE CASCADE actions.
#
# EVIDENCE-OF: R-61376-57267 A "CASCADE" action propagates the delete or
# update operation on the parent key to each dependent child key.
#
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
  }
} {}
do_test e_fkey-51.2 {
  execsql {
    UPDATE parent SET x = 22;
    SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
  }
} {21 22 23 xxx 22}
do_test e_fkey-51.3 {
  execsql {
    DELETE FROM child;
    DELETE FROM parent;
    INSERT INTO parent VALUES(-1);
    INSERT INTO child VALUES(-1);
    UPDATE parent SET x = 22;
    SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
  }
} {21 22 23 xxx 23}


#-------------------------------------------------------------------------
# Verify that ON UPDATE actions only actually take place if the parent key
# is set to a new value that is distinct from the old value. The default
# collation sequence and affinity are used to determine if the new value
# is 'distinct' from the old or not.







|









|







2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
  }
} {}
do_test e_fkey-51.2 {
  execsql {
    UPDATE parent SET x = 22;
    SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
  }
} {22 21 23 xxx 22}
do_test e_fkey-51.3 {
  execsql {
    DELETE FROM child;
    DELETE FROM parent;
    INSERT INTO parent VALUES(-1);
    INSERT INTO child VALUES(-1);
    UPDATE parent SET x = 22;
    SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
  }
} {22 23 21 xxx 23}


#-------------------------------------------------------------------------
# Verify that ON UPDATE actions only actually take place if the parent key
# is set to a new value that is distinct from the old value. The default
# collation sequence and affinity are used to determine if the new value
# is 'distinct' from the old or not.
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
  execsql {
    UPDATE zeus SET b = '1';
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 text 1}
do_test e_fkey-52.6 {
  execsql {
    UPDATE zeus SET b = x'1234';
    SELECT typeof(c), c, typeof(d), quote(d) FROM apollo;
  }
} {integer 1 blob x'1234'}

#-------------------------------------------------------------------------
# EVIDENCE-OF: R-35129-58141
#
# Test an example from the "ON DELETE and ON UPDATE Actions" section 
# of foreignkeys.html. This example demonstrates that ON UPDATE actions
# only take place if at least one parent key column is set to a value 







|
|

|







2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
  execsql {
    UPDATE zeus SET b = '1';
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 text 1}
do_test e_fkey-52.6 {
  execsql {
    UPDATE zeus SET b = NULL;
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 null {}}

#-------------------------------------------------------------------------
# EVIDENCE-OF: R-35129-58141
#
# Test an example from the "ON DELETE and ON UPDATE Actions" section 
# of foreignkeys.html. This example demonstrates that ON UPDATE actions
# only take place if at least one parent key column is set to a value 
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
    CREATE TABLE c7(c, d, 
      FOREIGN KEY(c, d) REFERENCES p ON DELETE NO ACTION
      DEFERRABLE INITIALLY DEFERRED
    );

    CREATE TABLE log(msg);
    CREATE TRIGGER tt AFTER DELETE ON p BEGIN
      INSERT INTO log VALUES('delete ' || old.a || '|' || old.b);
    END;
  }
} {}

do_test e_fkey-57.2 {
  execsql {
    INSERT INTO p VALUES('a', 'b');







|







2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
    CREATE TABLE c7(c, d, 
      FOREIGN KEY(c, d) REFERENCES p ON DELETE NO ACTION
      DEFERRABLE INITIALLY DEFERRED
    );

    CREATE TABLE log(msg);
    CREATE TRIGGER tt AFTER DELETE ON p BEGIN
      INSERT INTO log VALUES('delete ' || old.rowid);
    END;
  }
} {}

do_test e_fkey-57.2 {
  execsql {
    INSERT INTO p VALUES('a', 'b');
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
do_test e_fkey-57.7 {
  execsql {
    BEGIN;
      DELETE FROM p;
      SELECT * FROM log;
    ROLLBACK;
  }
} {{delete a|b}}

#-------------------------------------------------------------------------
# If an IMMEDIATE foreign key fails as a result of a DROP TABLE, the
# DROP TABLE command fails.
#
# EVIDENCE-OF: R-32768-47925 If an immediate foreign key constraint is
# violated, the DROP TABLE statement fails and the table is not dropped.







|







2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
do_test e_fkey-57.7 {
  execsql {
    BEGIN;
      DELETE FROM p;
      SELECT * FROM log;
    ROLLBACK;
  }
} {{delete 1}}

#-------------------------------------------------------------------------
# If an IMMEDIATE foreign key fails as a result of a DROP TABLE, the
# DROP TABLE command fails.
#
# EVIDENCE-OF: R-32768-47925 If an immediate foreign key constraint is
# violated, the DROP TABLE statement fails and the table is not dropped.
2706
2707
2708
2709
2710
2711
2712







2713
2714
2715
2716
2717
2718
2719
    INSERT INTO c3 VALUES(1, 2);
  }
} {}
do_test e_fkey-60.2 {
  execsql { PRAGMA foreign_keys = ON }
  catchsql { DELETE FROM p }
} {1 {no such table: main.nosuchtable}}








do_test e_fkey-60.3 {
  execsql {
    BEGIN;
      DROP TABLE p;
      SELECT * FROM c3;
    ROLLBACK;







>
>
>
>
>
>
>







2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
    INSERT INTO c3 VALUES(1, 2);
  }
} {}
do_test e_fkey-60.2 {
  execsql { PRAGMA foreign_keys = ON }
  catchsql { DELETE FROM p }
} {1 {no such table: main.nosuchtable}}


breakpoint
execsql { PRAGMA trace = 1 }
execsql { DROP TABLE p }
execsql { PRAGMA trace = 0 }


do_test e_fkey-60.3 {
  execsql {
    BEGIN;
      DROP TABLE p;
      SELECT * FROM c3;
    ROLLBACK;
Changes to test/e_insert.test.
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# EVIDENCE-OF: R-04006-57648 In this case the result of evaluating the
# left-most expression in the VALUES list is inserted into the left-most
# column of the new row, and so on.
#
delete_all_data
do_insert_tests e_insert-1.3 {
    1a   "INSERT INTO a2 VALUES(1, 2, 3)"    {}
    1b   "SELECT * FROM a2 WHERE rowid=(SELECT max(rowid) FROM a2)" {1 2 3}

    2a   "INSERT INTO a2 VALUES('abc', NULL, 3*3+1)"      {}
    2b   "SELECT * FROM a2 WHERE rowid=(SELECT max(rowid) FROM a2)" {abc {} 10}

    3a   "INSERT INTO a2 VALUES((SELECT count(*) FROM a2), 'x', 'y')" {}
    3b   "SELECT * FROM a2 WHERE rowid=(SELECT max(rowid) FROM a2)" {2 x y}
}

# EVIDENCE-OF: R-62524-00361 If a column-list is specified, then the
# number of values must match the number of specified columns.
#
do_insert_tests e_insert-1.4 -error { 
  %d values for %d columns







|


|


|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# EVIDENCE-OF: R-04006-57648 In this case the result of evaluating the
# left-most expression in the VALUES list is inserted into the left-most
# column of the new row, and so on.
#
delete_all_data
do_insert_tests e_insert-1.3 {
    1a   "INSERT INTO a2 VALUES(1, 2, 3)"    {}
    1b   "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {1 2 3}

    2a   "INSERT INTO a2 VALUES('abc', NULL, 3*3+1)"      {}
    2b   "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {abc {} 10}

    3a   "INSERT INTO a2 VALUES((SELECT count(*) FROM a2), 'x', 'y')" {}
    3b   "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {2 x y}
}

# EVIDENCE-OF: R-62524-00361 If a column-list is specified, then the
# number of values must match the number of specified columns.
#
do_insert_tests e_insert-1.4 -error { 
  %d values for %d columns
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
#    lang_replace.html.
#
do_execsql_test e_insert-4.1.0 {
  INSERT INTO a4 VALUES(1, 'a');
  INSERT INTO a4 VALUES(2, 'a');
  INSERT INTO a4 VALUES(3, 'a');
} {}
foreach {tn sql error ts data } {
  1.1  "INSERT INTO a4 VALUES(2,'b')"  {column c is not unique}  0 {1 a 2 a 3 a}
  1.2  "INSERT OR REPLACE INTO a4 VALUES(2, 'b')"            {}  0 {1 a 3 a 2 b}
  1.3  "INSERT OR IGNORE INTO a4 VALUES(3, 'c')"             {}  0 {1 a 3 a 2 b}
  1.4  "BEGIN" {} 1 {1 a 3 a 2 b}
  1.5  "INSERT INTO a4 VALUES(1, 'd')" {column c is not unique}  1 {1 a 3 a 2 b}
  1.6  "INSERT OR ABORT INTO a4 VALUES(1, 'd')" 
        {column c is not unique}  1 {1 a 3 a 2 b}
  1.7  "INSERT OR ROLLBACK INTO a4 VALUES(1, 'd')" 
        {column c is not unique}  0 {1 a 3 a 2 b}
  1.8  "INSERT INTO a4 SELECT 4, 'e' UNION ALL SELECT 3, 'e'"
        {column c is not unique}  0 {1 a 3 a 2 b}
  1.9  "INSERT OR FAIL INTO a4 SELECT 4, 'e' UNION ALL SELECT 3, 'e'"
        {column c is not unique}  0 {1 a 3 a 2 b 4 e}

  2.1  "INSERT INTO a4 VALUES(2,'f')"  
        {column c is not unique}  0 {1 a 3 a 2 b 4 e}
  2.2  "REPLACE INTO a4 VALUES(2, 'f')" {}  0 {1 a 3 a 4 e 2 f}
} {
  do_catchsql_test e_insert-4.1.$tn.1 $sql [list [expr {$error!=""}] $error]
  do_execsql_test  e_insert-4.1.$tn.2 {SELECT * FROM a4} [list {*}$data]
  do_test          e_insert-4.1.$tn.3 {sqlite4_db_transaction_status db} $ts
}

# EVIDENCE-OF: R-64196-02418 The optional "database-name." prefix on the
# table-name is support for top-level INSERT statements only.
#
# EVIDENCE-OF: R-05731-00924 The table name must be unqualified for
# INSERT statements that occur within CREATE TRIGGER statements.







|
|
|
|
|
|

|

|

|

|


|
|



|







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
#    lang_replace.html.
#
do_execsql_test e_insert-4.1.0 {
  INSERT INTO a4 VALUES(1, 'a');
  INSERT INTO a4 VALUES(2, 'a');
  INSERT INTO a4 VALUES(3, 'a');
} {}
foreach {tn sql error ac data } {
  1.1  "INSERT INTO a4 VALUES(2,'b')"  {column c is not unique}  1 {1 a 2 a 3 a}
  1.2  "INSERT OR REPLACE INTO a4 VALUES(2, 'b')"            {}  1 {1 a 3 a 2 b}
  1.3  "INSERT OR IGNORE INTO a4 VALUES(3, 'c')"             {}  1 {1 a 3 a 2 b}
  1.4  "BEGIN" {} 0 {1 a 3 a 2 b}
  1.5  "INSERT INTO a4 VALUES(1, 'd')" {column c is not unique}  0 {1 a 3 a 2 b}
  1.6  "INSERT OR ABORT INTO a4 VALUES(1, 'd')" 
        {column c is not unique}  0 {1 a 3 a 2 b}
  1.7  "INSERT OR ROLLBACK INTO a4 VALUES(1, 'd')" 
        {column c is not unique}  1 {1 a 3 a 2 b}
  1.8  "INSERT INTO a4 SELECT 4, 'e' UNION ALL SELECT 3, 'e'"
        {column c is not unique}  1 {1 a 3 a 2 b}
  1.9  "INSERT OR FAIL INTO a4 SELECT 4, 'e' UNION ALL SELECT 3, 'e'"
        {column c is not unique}  1 {1 a 3 a 2 b 4 e}

  2.1  "INSERT INTO a4 VALUES(2,'f')"  
        {column c is not unique}  1 {1 a 3 a 2 b 4 e}
  2.2  "REPLACE INTO a4 VALUES(2, 'f')" {}  1 {1 a 3 a 4 e 2 f}
} {
  do_catchsql_test e_insert-4.1.$tn.1 $sql [list [expr {$error!=""}] $error]
  do_execsql_test  e_insert-4.1.$tn.2 {SELECT * FROM a4} [list {*}$data]
  do_test          e_insert-4.1.$tn.3 {sqlite4_get_autocommit db} $ac
}

# EVIDENCE-OF: R-64196-02418 The optional "database-name." prefix on the
# table-name is support for top-level INSERT statements only.
#
# EVIDENCE-OF: R-05731-00924 The table name must be unqualified for
# INSERT statements that occur within CREATE TRIGGER statements.
Changes to test/e_reindex.test.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
  UPDATE sqlite_master SET sql = substr(sql, 4) WHERE type = 'index';
} {}

db close
sqlite4 db test.db
do_execsql_test e_reindex-1.3 {
  PRAGMA integrity_check;
} {{6 errors:
entry missing from index i2: 041810180e1808
entry missing from index i1: 03180e18101808
entry missing from index i2: 0418141812180a
entry missing from index i1: 0318121814180a
wrong # number of entries in index i2
wrong # number of entries in index i1
}}


do_execsql_test e_reindex-1.4 {
  REINDEX;
  PRAGMA integrity_check;
} {ok}

#-------------------------------------------------------------------------







|
|
|
|
|
|
|
<
>







62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
  UPDATE sqlite_master SET sql = substr(sql, 4) WHERE type = 'index';
} {}

db close
sqlite4 db test.db
do_execsql_test e_reindex-1.3 {
  PRAGMA integrity_check;
} [list \
  {rowid 4 missing from index i2} \
  {rowid 4 missing from index i1} \
  {rowid 5 missing from index i2} \
  {rowid 5 missing from index i1} \
  {wrong # of entries in index i2} \
  {wrong # of entries in index i1}

]

do_execsql_test e_reindex-1.4 {
  REINDEX;
  PRAGMA integrity_check;
} {ok}

#-------------------------------------------------------------------------
Changes to test/e_select.test.
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
#   These tests also show that the following is not untrue:
#
# EVIDENCE-OF: R-25883-55063 The expressions in the GROUP BY clause do
# not have to be expressions that appear in the result.
#
do_select_tests e_select-4.9 {
  1  "SELECT group_concat(one), two FROM b1 GROUP BY two" {
    4,5 f   1 o   6,7   s 2,3 t
  }
  2  "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" {
    1,2,3,4 10    5,6,7 18
  }
  3  "SELECT group_concat(one) FROM b1 GROUP BY (two>'o'), one%2" {
    4  1,5    2,6   3,7
  }
  4  "SELECT group_concat(one) FROM b1 GROUP BY (one==2 OR two=='o')" {
    3,4,5,6,7    1,2
  }
}

# EVIDENCE-OF: R-14926-50129 For the purposes of grouping rows, NULL
# values are considered equal.
#
do_select_tests e_select-4.10 {







|


|





|







1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
#   These tests also show that the following is not untrue:
#
# EVIDENCE-OF: R-25883-55063 The expressions in the GROUP BY clause do
# not have to be expressions that appear in the result.
#
do_select_tests e_select-4.9 {
  1  "SELECT group_concat(one), two FROM b1 GROUP BY two" {
    4,5 f   1 o   7,6   s 3,2 t
  }
  2  "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" {
    1,4,3,2 10    5,7,6 18
  }
  3  "SELECT group_concat(one) FROM b1 GROUP BY (two>'o'), one%2" {
    4  1,5    2,6   3,7
  }
  4  "SELECT group_concat(one) FROM b1 GROUP BY (one==2 OR two=='o')" {
    4,3,5,7,6    1,2
  }
}

# EVIDENCE-OF: R-14926-50129 For the purposes of grouping rows, NULL
# values are considered equal.
#
do_select_tests e_select-4.10 {
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
  INSERT INTO q3 VALUES('beauty', 2);
  INSERT INTO q3 VALUES('beauty', 2);
} {}
do_select_tests e_select-7.4 {
  1   {SELECT a FROM q1 UNION ALL SELECT d FROM q2}
      {16 legible beauty legible beauty -65.91 emanating}

  2   {SELECT * FROM q1 WHERE a=16 UNION ALL SELECT 'x',* FROM q2 WHERE rowid=1}
      {16 -87.66 {} x legible 1}

  3   {SELECT count(*) FROM q1 UNION ALL SELECT min(e) FROM q2} 
      {3 -16.56}

  4   {SELECT * FROM q2 UNION ALL SELECT * FROM q3} 
      {legible 1 beauty 2 -65.91 4 emanating -16.56 beauty 2 beauty 2}
} 

# EVIDENCE-OF: R-20560-39162 The UNION operator works the same way as
# UNION ALL, except that duplicate rows are removed from the final
# result set.
#
do_select_tests e_select-7.5 {
  1   {SELECT a FROM q1 UNION SELECT d FROM q2}
      {-65.91 16 beauty emanating legible}

  2   {SELECT * FROM q1 WHERE a=16 UNION SELECT 'x', * FROM q2 WHERE rowid=1}
      {16 -87.66 {} x legible 1}

  3   {SELECT count(*) FROM q1 UNION SELECT min(e) FROM q2} 
      {-16.56 3}

  4   {SELECT * FROM q2 UNION SELECT * FROM q3} 
      {-65.91 4 beauty 2 emanating -16.56 legible 1}







|

















|







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
  INSERT INTO q3 VALUES('beauty', 2);
  INSERT INTO q3 VALUES('beauty', 2);
} {}
do_select_tests e_select-7.4 {
  1   {SELECT a FROM q1 UNION ALL SELECT d FROM q2}
      {16 legible beauty legible beauty -65.91 emanating}

  2   {SELECT * FROM q1 WHERE a=16 UNION ALL SELECT 'x', * FROM q2 WHERE oid=1}
      {16 -87.66 {} x legible 1}

  3   {SELECT count(*) FROM q1 UNION ALL SELECT min(e) FROM q2} 
      {3 -16.56}

  4   {SELECT * FROM q2 UNION ALL SELECT * FROM q3} 
      {legible 1 beauty 2 -65.91 4 emanating -16.56 beauty 2 beauty 2}
} 

# EVIDENCE-OF: R-20560-39162 The UNION operator works the same way as
# UNION ALL, except that duplicate rows are removed from the final
# result set.
#
do_select_tests e_select-7.5 {
  1   {SELECT a FROM q1 UNION SELECT d FROM q2}
      {-65.91 16 beauty emanating legible}

  2   {SELECT * FROM q1 WHERE a=16 UNION SELECT 'x', * FROM q2 WHERE oid=1}
      {16 -87.66 {} x legible 1}

  3   {SELECT count(*) FROM q1 UNION SELECT min(e) FROM q2} 
      {-16.56 3}

  4   {SELECT * FROM q2 UNION SELECT * FROM q3} 
      {-65.91 4 beauty 2 emanating -16.56 legible 1}
Changes to test/e_update.test.
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# are set to the values found by evaluating the corresponding scalar
# expressions.
#
# EVIDENCE-OF: R-40472-60438 Columns that do not appear in the list of
# assignments are left unmodified.
#
do_execsql_test e_update-1.5.0 {
  INSERT INTO t2(a, b, c) VALUES(3, 1, 4);
  INSERT INTO t2(a, b, c) VALUES(1, 5, 9);
  INSERT INTO t2(a, b, c) VALUES(2, 6, 5);
} {}
do_update_tests e_update-1.5 -query {
  SELECT * FROM t2
} {
  1   "UPDATE t2 SET c = 1+1 WHERE a=2" 
      {3 1 4   1 5 9   2 6 2}








|
|
|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# are set to the values found by evaluating the corresponding scalar
# expressions.
#
# EVIDENCE-OF: R-40472-60438 Columns that do not appear in the list of
# assignments are left unmodified.
#
do_execsql_test e_update-1.5.0 {
  INSERT INTO t2(rowid, a, b, c) VALUES(1,  3, 1, 4);
  INSERT INTO t2(rowid, a, b, c) VALUES(2,  1, 5, 9);
  INSERT INTO t2(rowid, a, b, c) VALUES(3,  2, 6, 5);
} {}
do_update_tests e_update-1.5 -query {
  SELECT * FROM t2
} {
  1   "UPDATE t2 SET c = 1+1 WHERE a=2" 
      {3 1 4   1 5 9   2 6 2}

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
# of the row being updated.
#
# EVIDENCE-OF: R-04558-24451 In this case all scalar expressions are
# evaluated before any assignments are made.
#
do_execsql_test e_update-1.7.0 {
  DELETE FROM t2;
  INSERT INTO t2(a, b, c) VALUES(3, 1, 4);
  INSERT INTO t2(a, b, c) VALUES(1, 5, 9);
  INSERT INTO t2(a, b, c) VALUES(2, 6, 5);
} {}
do_update_tests e_update-1.7 -query {
  SELECT * FROM t2
} {
  1   "UPDATE t2 SET a=b+c"          {5 1 4     14 5 9   11  6 5}
  2   "UPDATE t2 SET a=b, b=a"       {1 5 4     5 14 9    6 11 5}
  3   "UPDATE t2 SET a=c||c, c=NULL" {44 5 {}  99 14 {}  55 11 {}}
}

# EVIDENCE-OF: R-12619-24112 The optional conflict-clause allows the
# user to nominate a specific constraint conflict resolution algorithm
# to use during this one UPDATE command.
#
do_execsql_test e_update-1.8.0 {
  DELETE FROM t3;
  INSERT INTO t3 VALUES(1, 'one');
  INSERT INTO t3 VALUES(2, 'two');
  INSERT INTO t3 VALUES(3, 'three');
  INSERT INTO t3 VALUES(4, 'four');
} {}
foreach {tn sql error ts data } {
  1  "UPDATE t3 SET b='one' WHERE a=3" 
     {column b is not unique} 0 {1 one 2 two 3 three 4 four}

  2  "UPDATE OR REPLACE t3 SET b='one' WHERE a=3" 
     {} 0 {2 two 3 one 4 four}

  3  "UPDATE OR FAIL t3 SET b='three'"
     {column b is not unique} 0 {2 three 3 one 4 four}

  4  "UPDATE OR IGNORE t3 SET b='three' WHERE a=3" 
     {} 0 {2 three 3 one 4 four}

  5  "UPDATE OR ABORT t3 SET b='three' WHERE a=3" 
     {column b is not unique} 0 {2 three 3 one 4 four}

  6  "BEGIN" {} 1 {2 three 3 one 4 four}

  7  "UPDATE t3 SET b='three' WHERE a=3" 
     {column b is not unique} 1 {2 three 3 one 4 four}

  8  "UPDATE OR ABORT t3 SET b='three' WHERE a=3" 
     {column b is not unique} 1 {2 three 3 one 4 four}

  9  "UPDATE OR FAIL t3 SET b='two'"
     {column b is not unique} 1 {2 two 3 one 4 four}

  10 "UPDATE OR IGNORE t3 SET b='four' WHERE a=3"
     {} 1 {2 two 3 one 4 four}

  11 "UPDATE OR REPLACE t3 SET b='four' WHERE a=3"
     {} 1 {2 two 3 four}

  12 "UPDATE OR ROLLBACK t3 SET b='four'"
     {column b is not unique} 0 {2 three 3 one 4 four}
} {
  do_catchsql_test e_update-1.8.$tn.1 $sql [list [expr {$error!=""}] $error]
  do_execsql_test  e_update-1.8.$tn.2 {SELECT * FROM t3} [list {*}$data]
  do_test          e_update-1.8.$tn.3 {sqlite4_db_transaction_status db} $ts
}



# EVIDENCE-OF: R-12123-54095 The table-name specified as part of an
# UPDATE statement within a trigger body must be unqualified.
#







|
|
|




















|

|


|


|


|


|

|


|


|


|


|


|


|



|







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
# of the row being updated.
#
# EVIDENCE-OF: R-04558-24451 In this case all scalar expressions are
# evaluated before any assignments are made.
#
do_execsql_test e_update-1.7.0 {
  DELETE FROM t2;
  INSERT INTO t2(rowid, a, b, c) VALUES(1,  3, 1, 4);
  INSERT INTO t2(rowid, a, b, c) VALUES(2,  1, 5, 9);
  INSERT INTO t2(rowid, a, b, c) VALUES(3,  2, 6, 5);
} {}
do_update_tests e_update-1.7 -query {
  SELECT * FROM t2
} {
  1   "UPDATE t2 SET a=b+c"          {5 1 4     14 5 9   11  6 5}
  2   "UPDATE t2 SET a=b, b=a"       {1 5 4     5 14 9    6 11 5}
  3   "UPDATE t2 SET a=c||c, c=NULL" {44 5 {}  99 14 {}  55 11 {}}
}

# EVIDENCE-OF: R-12619-24112 The optional conflict-clause allows the
# user to nominate a specific constraint conflict resolution algorithm
# to use during this one UPDATE command.
#
do_execsql_test e_update-1.8.0 {
  DELETE FROM t3;
  INSERT INTO t3 VALUES(1, 'one');
  INSERT INTO t3 VALUES(2, 'two');
  INSERT INTO t3 VALUES(3, 'three');
  INSERT INTO t3 VALUES(4, 'four');
} {}
foreach {tn sql error ac data } {
  1  "UPDATE t3 SET b='one' WHERE a=3" 
     {column b is not unique} 1 {1 one 2 two 3 three 4 four}

  2  "UPDATE OR REPLACE t3 SET b='one' WHERE a=3" 
     {} 1 {2 two 3 one 4 four}

  3  "UPDATE OR FAIL t3 SET b='three'"
     {column b is not unique} 1 {2 three 3 one 4 four}

  4  "UPDATE OR IGNORE t3 SET b='three' WHERE a=3" 
     {} 1 {2 three 3 one 4 four}

  5  "UPDATE OR ABORT t3 SET b='three' WHERE a=3" 
     {column b is not unique} 1 {2 three 3 one 4 four}

  6  "BEGIN" {} 0 {2 three 3 one 4 four}

  7  "UPDATE t3 SET b='three' WHERE a=3" 
     {column b is not unique} 0 {2 three 3 one 4 four}

  8  "UPDATE OR ABORT t3 SET b='three' WHERE a=3" 
     {column b is not unique} 0 {2 three 3 one 4 four}

  9  "UPDATE OR FAIL t3 SET b='two'"
     {column b is not unique} 0 {2 two 3 one 4 four}

  10 "UPDATE OR IGNORE t3 SET b='four' WHERE a=3"
     {} 0 {2 two 3 one 4 four}

  11 "UPDATE OR REPLACE t3 SET b='four' WHERE a=3"
     {} 0 {2 two 3 four}

  12 "UPDATE OR ROLLBACK t3 SET b='four'"
     {column b is not unique} 1 {2 three 3 one 4 four}
} {
  do_catchsql_test e_update-1.8.$tn.1 $sql [list [expr {$error!=""}] $error]
  do_execsql_test  e_update-1.8.$tn.2 {SELECT * FROM t3} [list {*}$data]
  do_test          e_update-1.8.$tn.3 {sqlite4_get_autocommit db} $ac
}



# EVIDENCE-OF: R-12123-54095 The table-name specified as part of an
# UPDATE statement within a trigger body must be unqualified.
#
Changes to test/enc2.test.
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
do_test $t.3 {
  execsql {
    INSERT INTO t1 VALUES('three','III',3);
    INSERT INTO t1 VALUES('four','IV',4);
    INSERT INTO t1 VALUES('five','V',5);
  }
  execsql {SELECT * FROM t1}
} {five V 5 four IV 4 one I 1 three III 3 two II 2}

# Use the index
do_test $t.4 {
  execsql {
    SELECT * FROM t1 WHERE a = 'one';
  }
} {one I 1}







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
do_test $t.3 {
  execsql {
    INSERT INTO t1 VALUES('three','III',3);
    INSERT INTO t1 VALUES('four','IV',4);
    INSERT INTO t1 VALUES('five','V',5);
  }
  execsql {SELECT * FROM t1}
} {one I 1 two II 2 three III 3 four IV 4 five V 5}

# Use the index
do_test $t.4 {
  execsql {
    SELECT * FROM t1 WHERE a = 'one';
  }
} {one I 1}
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127




128
129
130
131
132
133
134
}

# Now check that we can retrieve data in both UTF-16 and UTF-8
do_test $t.7 {
  set STMT [sqlite4_prepare $DB "SELECT a FROM t1 WHERE c>3;" -1 TAIL]
  sqlite4_step $STMT
  sqlite4_column_text $STMT 0
} {five}

do_test $t.8 {
  sqlite4_step $STMT
  utf8 [sqlite4_column_text16 $STMT 0]
} {four}

do_test $t.9 {
  sqlite4_finalize $STMT
} SQLITE4_OK





do_test $t.10 {
  db eval {PRAGMA encoding}
} $enc

}








|




|




>
>
>
>







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
}

# Now check that we can retrieve data in both UTF-16 and UTF-8
do_test $t.7 {
  set STMT [sqlite4_prepare $DB "SELECT a FROM t1 WHERE c>3;" -1 TAIL]
  sqlite4_step $STMT
  sqlite4_column_text $STMT 0
} {four}

do_test $t.8 {
  sqlite4_step $STMT
  utf8 [sqlite4_column_text16 $STMT 0]
} {five}

do_test $t.9 {
  sqlite4_finalize $STMT
} SQLITE4_OK

ifcapable vacuum {
  execsql VACUUM
}

do_test $t.10 {
  db eval {PRAGMA encoding}
} $enc

}

Changes to test/enc3.test.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
      SELECT * FROM t1
    }
  } {abcdef {}}
  do_test enc3-1.5 {
    execsql {
      SELECT quote(x) || ' ' || quote(y) FROM t1
    }
  } {{x'616263646566' NULL}}
}
ifcapable {bloblit && utf16} {
  do_test enc3-2.1 {
    execsql {
      PRAGMA encoding
    }
  } {UTF-16le}







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
      SELECT * FROM t1
    }
  } {abcdef {}}
  do_test enc3-1.5 {
    execsql {
      SELECT quote(x) || ' ' || quote(y) FROM t1
    }
  } {{X'616263646566' NULL}}
}
ifcapable {bloblit && utf16} {
  do_test enc3-2.1 {
    execsql {
      PRAGMA encoding
    }
  } {UTF-16le}
Changes to test/errmsg.test.
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
  lappend ret [sqlite4_finalize $stmt]
  lappend ret [sqlite4_errmsg db]

  set ret
}

proc error_messages_v2 {sql {schema {}}} {
  error_messages_worker sqlite4_prepare $sql $schema
}

proc error_messages {sql {schema {}}} {
  error_messages_worker sqlite4_prepare $sql $schema
}

proc sql_error {msg} { error $msg }
db func sql_error sql_error

#-------------------------------------------------------------------------
# Test error messages returned by user-defined SQL functions.
#
do_test 1.1 {
  error_messages "SELECT sql_error('custom message')"
} [list {*}{
    SQLITE4_ERROR {custom message}
    SQLITE4_ERROR {custom message}
}]
do_test 1.2 {
  error_messages_v2 "SELECT sql_error('custom message')"
} [list {*}{
    SQLITE4_ERROR {custom message}
    SQLITE4_ERROR {custom message}
}]

#-------------------------------------------------------------------------
# Test error messages generated directly by VDBE code (e.g. constraint
# failures).
#
do_execsql_test 2.1 {
  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t1 VALUES('abc', 'def');
}
do_test 2.2 {
  error_messages "INSERT INTO t1 VALUES('ghi', 'def')"
} [list {*}{
    SQLITE4_CONSTRAINT {column b is not unique}
    SQLITE4_CONSTRAINT {column b is not unique}
}]
do_test 2.3 {
  error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')"
} [list {*}{
    SQLITE4_CONSTRAINT {column b is not unique}
    SQLITE4_CONSTRAINT {column b is not unique}







|















|




















|







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
  lappend ret [sqlite4_finalize $stmt]
  lappend ret [sqlite4_errmsg db]

  set ret
}

proc error_messages_v2 {sql {schema {}}} {
  error_messages_worker sqlite4_prepare_v2 $sql $schema
}

proc error_messages {sql {schema {}}} {
  error_messages_worker sqlite4_prepare $sql $schema
}

proc sql_error {msg} { error $msg }
db func sql_error sql_error

#-------------------------------------------------------------------------
# Test error messages returned by user-defined SQL functions.
#
do_test 1.1 {
  error_messages "SELECT sql_error('custom message')"
} [list {*}{
    SQLITE4_ERROR {SQL logic error or missing database} 
    SQLITE4_ERROR {custom message}
}]
do_test 1.2 {
  error_messages_v2 "SELECT sql_error('custom message')"
} [list {*}{
    SQLITE4_ERROR {custom message}
    SQLITE4_ERROR {custom message}
}]

#-------------------------------------------------------------------------
# Test error messages generated directly by VDBE code (e.g. constraint
# failures).
#
do_execsql_test 2.1 {
  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t1 VALUES('abc', 'def');
}
do_test 2.2 {
  error_messages "INSERT INTO t1 VALUES('ghi', 'def')"
} [list {*}{
    SQLITE4_ERROR      {SQL logic error or missing database} 
    SQLITE4_CONSTRAINT {column b is not unique}
}]
do_test 2.3 {
  error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')"
} [list {*}{
    SQLITE4_CONSTRAINT {column b is not unique}
    SQLITE4_CONSTRAINT {column b is not unique}
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
do_execsql_test 3.1.1 {
  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t2 VALUES('abc', 'def');
}
do_test 3.1.2 {
  error_messages "SELECT a FROM t2" "DROP TABLE t2"
} [list {*}{
    SQLITE4_ERROR {no such table: t2} 
    SQLITE4_ERROR {no such table: t2}
}]
do_execsql_test 3.2.1 {
  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t2 VALUES('abc', 'def');
}
do_test 3.2.2 {
  error_messages_v2 "SELECT a FROM t2" "DROP TABLE t2"
} [list {*}{
    SQLITE4_ERROR {no such table: t2} 
    SQLITE4_ERROR {no such table: t2}
}]

finish_test







|
|













95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
do_execsql_test 3.1.1 {
  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t2 VALUES('abc', 'def');
}
do_test 3.1.2 {
  error_messages "SELECT a FROM t2" "DROP TABLE t2"
} [list {*}{
    SQLITE4_ERROR {SQL logic error or missing database} 
    SQLITE4_SCHEMA {database schema has changed}
}]
do_execsql_test 3.2.1 {
  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t2 VALUES('abc', 'def');
}
do_test 3.2.2 {
  error_messages_v2 "SELECT a FROM t2" "DROP TABLE t2"
} [list {*}{
    SQLITE4_ERROR {no such table: t2} 
    SQLITE4_ERROR {no such table: t2}
}]

finish_test
Changes to test/eval.test.
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
#
do_test eval-2.1 {
  execsql {
    CREATE TABLE t2(x,y);
    INSERT INTO t2 SELECT x, x+1 FROM t1 WHERE x<5;
    SELECT x, test_eval('DELETE FROM t2 WHERE x='||x), y FROM t2;
  }
} {1 {} 2 2 {} 3 3 {} 4 4 {} 5}
do_test eval-2.2 {
  execsql {
    SELECT * FROM t2
  }
} {}

# Modify a row while it is being read.
#
do_test eval-3.1 {
  execsql {
    INSERT INTO t2 SELECT x, x+1 FROM t1 WHERE x<5;
    SELECT x, test_eval('UPDATE t2 SET y=y+100 WHERE x='||x), y FROM t2;
  }
} {1 {} 2 2 {} 3 3 {} 4 4 {} 5}

do_test eval-4.1 {
  execsql { SELECT test_eval('SELECT ''abcdefghij''') }
} {abcdefghij}

finish_test







|













|


|



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
#
do_test eval-2.1 {
  execsql {
    CREATE TABLE t2(x,y);
    INSERT INTO t2 SELECT x, x+1 FROM t1 WHERE x<5;
    SELECT x, test_eval('DELETE FROM t2 WHERE x='||x), y FROM t2;
  }
} {1 {} {} 2 {} {} 3 {} {} 4 {} {}}
do_test eval-2.2 {
  execsql {
    SELECT * FROM t2
  }
} {}

# Modify a row while it is being read.
#
do_test eval-3.1 {
  execsql {
    INSERT INTO t2 SELECT x, x+1 FROM t1 WHERE x<5;
    SELECT x, test_eval('UPDATE t2 SET y=y+100 WHERE x='||x), y FROM t2;
  }
} {1 {} 102 2 {} 103 3 {} 104 4 {} 105}

do_test eval-4.1 {
  execsql { SELECT test_eval('SELECT "abcdefghij"') }
} {abcdefghij}

finish_test
Changes to test/expr.test.
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
  test_expr expr-2.19 {r1=2.34, r2=2.34} {r2=r1} 1
  test_expr expr-2.20 {r1=2.34, r2=2.34} {r2<>r1} 0
  test_expr expr-2.21 {r1=2.34, r2=2.34} {r2==r1} 1
  test_expr expr-2.22 {r1=1.23, r2=2.34} {min(r1,r2,r1+r2,r1-r2)} {-1.11}
  test_expr expr-2.23 {r1=1.23, r2=2.34} {max(r1,r2,r1+r2,r1-r2)} {3.57}
  test_expr expr-2.24 {r1=25.0, r2=11.0} {r1%r2} 3.0
  test_expr expr-2.25 {r1=1.23, r2=NULL} {coalesce(r1+r2,99.0)} 99.0
  test_expr expr-2.26 {r1=1e600, r2=1e600} {coalesce((r1*r2)*0.0,99.0)} 99.0
  test_expr expr-2.26b {r1=1e300, r2=-1e300} {coalesce((r1*r2)*0.0,99.0)} 0.0
  test_expr expr-2.27 {r1=1.1, r2=0.0} {r1/r2} {{}}
  test_expr expr-2.28 {r1=1.1, r2=0.0} {r1%r2} {{}}
}

test_expr expr-3.1 {t1='abc', t2='xyz'} {t1<t2} 1
test_expr expr-3.2 {t1='xyz', t2='abc'} {t1<t2} 0
test_expr expr-3.3 {t1='abc', t2='abc'} {t1<t2} 0







|
|







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
  test_expr expr-2.19 {r1=2.34, r2=2.34} {r2=r1} 1
  test_expr expr-2.20 {r1=2.34, r2=2.34} {r2<>r1} 0
  test_expr expr-2.21 {r1=2.34, r2=2.34} {r2==r1} 1
  test_expr expr-2.22 {r1=1.23, r2=2.34} {min(r1,r2,r1+r2,r1-r2)} {-1.11}
  test_expr expr-2.23 {r1=1.23, r2=2.34} {max(r1,r2,r1+r2,r1-r2)} {3.57}
  test_expr expr-2.24 {r1=25.0, r2=11.0} {r1%r2} 3.0
  test_expr expr-2.25 {r1=1.23, r2=NULL} {coalesce(r1+r2,99.0)} 99.0
  test_expr expr-2.26 {r1=1e300, r2=1e300} {coalesce((r1*r2)*0.0,99.0)} 99.0
  test_expr expr-2.26b {r1=1e300, r2=-1e300} {coalesce((r1*r2)*0.0,99.0)} 99.0
  test_expr expr-2.27 {r1=1.1, r2=0.0} {r1/r2} {{}}
  test_expr expr-2.28 {r1=1.1, r2=0.0} {r1%r2} {{}}
}

test_expr expr-3.1 {t1='abc', t2='xyz'} {t1<t2} 1
test_expr expr-3.2 {t1='xyz', t2='abc'} {t1<t2} 0
test_expr expr-3.3 {t1='abc', t2='abc'} {t1<t2} 0
Changes to test/fuzz.test.
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
if {[info exists ::G(isquick)]} {
  if {$::G(isquick)} { set ::REPEATS 20 }
}

source $testdir/fuzz_common.tcl
expr srand(0)

proc zeroblob {n} {
  set L 0
  while {[llength $L] < $n} { set L [concat $L $L] }
  binary format c$n $L
}
db func zeroblob zeroblob

#----------------------------------------------------------------
# These tests caused errors that were first caught by the tests
# in this file. They are still here.
do_test fuzz-1.1 {
  execsql {
    SELECT 'abc' LIKE X'ABCD';
  }







<
<
<
<
<
<
<







30
31
32
33
34
35
36







37
38
39
40
41
42
43
if {[info exists ::G(isquick)]} {
  if {$::G(isquick)} { set ::REPEATS 20 }
}

source $testdir/fuzz_common.tcl
expr srand(0)








#----------------------------------------------------------------
# These tests caused errors that were first caught by the tests
# in this file. They are still here.
do_test fuzz-1.1 {
  execsql {
    SELECT 'abc' LIKE X'ABCD';
  }
Changes to test/in3.test.
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

do_test in3-1.1 {
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    INSERT INTO t1 VALUES(1, 2);
    INSERT INTO t1 VALUES(3, 4);
    INSERT INTO t1 VALUES(5, 6);

    CREATE TABLE t2(a, b);
    INSERT INTO t2 VALUES(1, 2);
    INSERT INTO t2 VALUES(3, 4);
    INSERT INTO t2 VALUES(5, 6);
  }
} {}

# All of these queries should avoid using a temp-table:
#
do_test in3-1.2 {
  exec_neph { SELECT rowid FROM t2 WHERE rowid IN (SELECT rowid FROM t2); }
} {0 1 2 3}
do_test in3-1.3 {
  exec_neph { SELECT a FROM t1 WHERE a IN (SELECT a FROM t1); }
} {0 1 3 5}
do_test in3-1.4 {
  exec_neph { SELECT rowid FROM t2 WHERE rowid+0 IN (SELECT rowid FROM t2); }
} {0 1 2 3}
do_test in3-1.5 {
  exec_neph { SELECT a FROM t1 WHERE a+0 IN (SELECT a FROM t1); }
} {0 1 3 5}

# Because none of the sub-select queries in the following statements
# match the pattern ("SELECT <column> FROM <table>"), the following do 
# require a temp table.
#
do_test in3-1.6 {
  exec_neph { SELECT rowid FROM t2 WHERE rowid IN (SELECT rowid+0 FROM t2); }
} {1 1 2 3}
do_test in3-1.7 {
  exec_neph { SELECT a FROM t1 WHERE a IN (SELECT a+0 FROM t1); }
} {1 1 3 5}
do_test in3-1.8 {
  exec_neph { SELECT a FROM t1 WHERE a IN (SELECT a FROM t1 WHERE 1); }
} {1 1 3 5}







<
<
<
<
<






|





|










|







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

do_test in3-1.1 {
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    INSERT INTO t1 VALUES(1, 2);
    INSERT INTO t1 VALUES(3, 4);
    INSERT INTO t1 VALUES(5, 6);





  }
} {}

# All of these queries should avoid using a temp-table:
#
do_test in3-1.2 {
  exec_neph { SELECT rowid FROM t1 WHERE rowid IN (SELECT rowid FROM t1); }
} {0 1 2 3}
do_test in3-1.3 {
  exec_neph { SELECT a FROM t1 WHERE a IN (SELECT a FROM t1); }
} {0 1 3 5}
do_test in3-1.4 {
  exec_neph { SELECT rowid FROM t1 WHERE rowid+0 IN (SELECT rowid FROM t1); }
} {0 1 2 3}
do_test in3-1.5 {
  exec_neph { SELECT a FROM t1 WHERE a+0 IN (SELECT a FROM t1); }
} {0 1 3 5}

# Because none of the sub-select queries in the following statements
# match the pattern ("SELECT <column> FROM <table>"), the following do 
# require a temp table.
#
do_test in3-1.6 {
  exec_neph { SELECT rowid FROM t1 WHERE rowid IN (SELECT rowid+0 FROM t1); }
} {1 1 2 3}
do_test in3-1.7 {
  exec_neph { SELECT a FROM t1 WHERE a IN (SELECT a+0 FROM t1); }
} {1 1 3 5}
do_test in3-1.8 {
  exec_neph { SELECT a FROM t1 WHERE a IN (SELECT a FROM t1 WHERE 1); }
} {1 1 3 5}
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
#
do_test in3-1.14 {
  exec_neph { SELECT a FROM t1 WHERE a COLLATE nocase IN (SELECT a FROM t1) }
} {1 1 3 5}
do_test in3-1.15 {
  exec_neph { SELECT a FROM t1 WHERE a COLLATE binary IN (SELECT a FROM t1) }
} {0 1 3 5}











# The following tests - in3.2.* - test a bug that was difficult to track
# down during development. They are not particularly well focused.
#
do_test in3-2.1 {
  execsql {
    DROP TABLE IF EXISTS t1;
    DROP TABLE IF EXISTS t2;
    CREATE TABLE t1(w int, x int, y int);
    CREATE TABLE t2(p int, q int, r int, s int);
  }
  for {set i 1} {$i<=100} {incr i} {
    set w $i
    set x [expr {int(log($i)/log(2))}]
    set y [expr {$i*$i + 2*$i + 1}]
    execsql "INSERT INTO t1 VALUES($w,$x,$y)"
  }
  set maxy [execsql {select max(y) from t1}]
  db eval { INSERT INTO t2 SELECT 101-w, x, $maxy+1-y, y FROM t1 }
} {}
do_test in3-2.2 {
  execsql {
    SELECT rowid 
    FROM t2 
    WHERE rowid IN (SELECT rowid FROM t2 WHERE rowid IN (1, 2));
  }
} {1 2}
do_test in3-2.3 {
  execsql {
    select rowid from t2 where rowid IN (-1,2,4)
  }
} {2 4}
do_test in3-2.4 {
  execsql {
    SELECT rowid FROM t2 WHERE rowid IN 
       (select rowid from t2 where rowid IN (-1,2,4))
  }
} {2 4}

#-------------------------------------------------------------------------
# This next block of tests - in3-3.* - verify that column affinity is
# correctly handled in cases where an index might be used to optimise
# an IN (SELECT) expression.







>
>
>
>
>
>
>
>
>
>







<















|
|




|




|
|







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
#
do_test in3-1.14 {
  exec_neph { SELECT a FROM t1 WHERE a COLLATE nocase IN (SELECT a FROM t1) }
} {1 1 3 5}
do_test in3-1.15 {
  exec_neph { SELECT a FROM t1 WHERE a COLLATE binary IN (SELECT a FROM t1) }
} {0 1 3 5}

# Neither of these queries require a temp-table. The collation sequence
# makes no difference when using a rowid.
#
do_test in3-1.16 {
  exec_neph {SELECT a FROM t1 WHERE a COLLATE nocase IN (SELECT rowid FROM t1)}
} {0 1 3}
do_test in3-1.17 {
  exec_neph {SELECT a FROM t1 WHERE a COLLATE binary IN (SELECT rowid FROM t1)}
} {0 1 3}

# The following tests - in3.2.* - test a bug that was difficult to track
# down during development. They are not particularly well focused.
#
do_test in3-2.1 {
  execsql {
    DROP TABLE IF EXISTS t1;

    CREATE TABLE t1(w int, x int, y int);
    CREATE TABLE t2(p int, q int, r int, s int);
  }
  for {set i 1} {$i<=100} {incr i} {
    set w $i
    set x [expr {int(log($i)/log(2))}]
    set y [expr {$i*$i + 2*$i + 1}]
    execsql "INSERT INTO t1 VALUES($w,$x,$y)"
  }
  set maxy [execsql {select max(y) from t1}]
  db eval { INSERT INTO t2 SELECT 101-w, x, $maxy+1-y, y FROM t1 }
} {}
do_test in3-2.2 {
  execsql {
    SELECT rowid 
    FROM t1 
    WHERE rowid IN (SELECT rowid FROM t1 WHERE rowid IN (1, 2));
  }
} {1 2}
do_test in3-2.3 {
  execsql {
    select rowid from t1 where rowid IN (-1,2,4)
  }
} {2 4}
do_test in3-2.4 {
  execsql {
    SELECT rowid FROM t1 WHERE rowid IN 
       (select rowid from t1 where rowid IN (-1,2,4))
  }
} {2 4}

#-------------------------------------------------------------------------
# This next block of tests - in3-3.* - verify that column affinity is
# correctly handled in cases where an index might be used to optimise
# an IN (SELECT) expression.
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  exec_neph { SELECT 'TEXT' COLLATE nocase IN (SELECT b FROM t3) }
} {1 1}
do_test in3-4.4 {
  # A temp table must be used because t3_i.b is not guaranteed to be unique.
  exec_neph { SELECT b FROM t3 WHERE b IN (SELECT b FROM t3) }
} {1 none numeric real text}
do_test in3-4.5 {
  execsql { CREATE UNIQUE INDEX t3_i2 ON t3(b) COVERING (b) }
  exec_neph { SELECT b FROM t3 WHERE b IN (SELECT b FROM t3) ORDER BY b}
} {0 none numeric real text}
do_test in3-4.6 {
  execsql { DROP INDEX t3_i2 }
} {}

# The following two test cases verify that ticket #2991 has been fixed.
#







|
|







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  exec_neph { SELECT 'TEXT' COLLATE nocase IN (SELECT b FROM t3) }
} {1 1}
do_test in3-4.4 {
  # A temp table must be used because t3_i.b is not guaranteed to be unique.
  exec_neph { SELECT b FROM t3 WHERE b IN (SELECT b FROM t3) }
} {1 none numeric real text}
do_test in3-4.5 {
  execsql { CREATE UNIQUE INDEX t3_i2 ON t3(b) }
  exec_neph { SELECT b FROM t3 WHERE b IN (SELECT b FROM t3) }
} {0 none numeric real text}
do_test in3-4.6 {
  execsql { DROP INDEX t3_i2 }
} {}

# The following two test cases verify that ticket #2991 has been fixed.
#
Changes to test/index.test.
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  execsql {SELECT f1 FROM test1 WHERE f2=65536}
} {16}
do_test index-7.3 {
  execsql {
    SELECT name FROM sqlite_master 
    WHERE type='index' AND tbl_name='test1'
  }
} {}
do_test index-7.4 {
  execsql {DROP table test1}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
integrity_check index-7.5

# Make sure we cannot drop a non-existant index.







|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  execsql {SELECT f1 FROM test1 WHERE f2=65536}
} {16}
do_test index-7.3 {
  execsql {
    SELECT name FROM sqlite_master 
    WHERE type='index' AND tbl_name='test1'
  }
} {sqlite_autoindex_test1_1}
do_test index-7.4 {
  execsql {DROP table test1}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
integrity_check index-7.5

# Make sure we cannot drop a non-existant index.
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
      PRIMARY KEY(b)
    );
  }
  for {set i 1} {$i<=50} {incr i} {
    execsql "INSERT INTO t3 VALUES('x${i}x',$i,0.$i)"
  }
  set sqlite_search_count 0
  execsql {SELECT c FROM t3 WHERE b==10}
} {0.1}
integrity_check index-11.2


# Numeric strings should compare as if they were numbers.  So even if the
# strings are not character-by-character the same, if they represent the
# same number they should compare equal to one another.  Verify that this
# is true in indices.







|
|







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
      PRIMARY KEY(b)
    );
  }
  for {set i 1} {$i<=50} {incr i} {
    execsql "INSERT INTO t3 VALUES('x${i}x',$i,0.$i)"
  }
  set sqlite_search_count 0
  concat [execsql {SELECT c FROM t3 WHERE b==10}] $sqlite_search_count
} {0.1 2}
integrity_check index-11.2


# Numeric strings should compare as if they were numbers.  So even if the
# strings are not character-by-character the same, if they represent the
# same number they should compare equal to one another.  Verify that this
# is true in indices.
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
   );
   INSERT INTO t5 VALUES(1,2,3);
   SELECT * FROM t5;
  }
} {1 2.0 3}
do_test index-13.2 {
  set ::idxlist [execsql {
    SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='t5';
  }]
  llength $::idxlist
} {2}
for {set i 0} {$i<[llength $::idxlist]} {incr i} {
  do_test index-13.3.$i {
    catchsql "
      DROP INDEX '[lindex $::idxlist $i]';
    "
  } {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}}
}







|


|







424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
   );
   INSERT INTO t5 VALUES(1,2,3);
   SELECT * FROM t5;
  }
} {1 2.0 3}
do_test index-13.2 {
  set ::idxlist [execsql {
    SELECT name FROM sqlite_master WHERE type="index" AND tbl_name="t5";
  }]
  llength $::idxlist
} {3}
for {set i 0} {$i<[llength $::idxlist]} {incr i} {
  do_test index-13.3.$i {
    catchsql "
      DROP INDEX '[lindex $::idxlist $i]';
    "
  } {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}}
}
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
} {1}
do_test index-16.3 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c PRIMARY KEY, UNIQUE(c) );
    SELECT count(*) FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {0}
do_test index-16.4 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c, d , UNIQUE(c, d), PRIMARY KEY(c, d) );
    SELECT count(*) FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {1}
do_test index-16.5 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c, d , UNIQUE(c), PRIMARY KEY(c, d) );
    SELECT count(*) FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {1}

# Test that automatically create indices are named correctly. The current
# convention is: "sqlite_autoindex_<table name>_<integer>"
#
# Then check that it is an error to try to drop any automtically created
# indices.
do_test index-17.1 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c, d UNIQUE, UNIQUE(c), PRIMARY KEY(c, d) );
    SELECT name FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {sqlite_t7_unique1 sqlite_t7_unique2}
do_test index-17.2 {
  catchsql {
    DROP INDEX sqlite_t7_unique1;
  }
} {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}}
do_test index-17.3 {
  catchsql {
    DROP INDEX IF EXISTS sqlite_t7_unique1;
  }
} {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}}
do_test index-17.4 {
  catchsql {
    DROP INDEX IF EXISTS no_such_index;
  }
} {0 {}}







|













|












|


|




|







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
} {1}
do_test index-16.3 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c PRIMARY KEY, UNIQUE(c) );
    SELECT count(*) FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {1}
do_test index-16.4 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c, d , UNIQUE(c, d), PRIMARY KEY(c, d) );
    SELECT count(*) FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {1}
do_test index-16.5 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c, d , UNIQUE(c), PRIMARY KEY(c, d) );
    SELECT count(*) FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {2}

# Test that automatically create indices are named correctly. The current
# convention is: "sqlite_autoindex_<table name>_<integer>"
#
# Then check that it is an error to try to drop any automtically created
# indices.
do_test index-17.1 {
  execsql {
    DROP TABLE t7;
    CREATE TABLE t7(c, d UNIQUE, UNIQUE(c), PRIMARY KEY(c, d) );
    SELECT name FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index';
  }
} {sqlite_autoindex_t7_1 sqlite_autoindex_t7_2 sqlite_autoindex_t7_3}
do_test index-17.2 {
  catchsql {
    DROP INDEX sqlite_autoindex_t7_1;
  }
} {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}}
do_test index-17.3 {
  catchsql {
    DROP INDEX IF EXISTS sqlite_autoindex_t7_1;
  }
} {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}}
do_test index-17.4 {
  catchsql {
    DROP INDEX IF EXISTS no_such_index;
  }
} {0 {}}
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
    }
  } {}
  do_test index-19.2 {
    catchsql {
      BEGIN;
      INSERT INTO t7 VALUES(1);
    }
  } {1 {PRIMARY KEY must be unique}}
  do_test index-19.3 {
    catchsql {
      BEGIN;
    }
  } {1 {cannot start a transaction within a transaction}}
  do_test index-19.4 {
    catchsql {
      INSERT INTO t8 VALUES(1);
    }
  } {1 {PRIMARY KEY must be unique}}
  do_test index-19.5 {
    catchsql {
      BEGIN;
      COMMIT;
    }
  } {0 {}}
  do_test index-19.6 {







|









|







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
    }
  } {}
  do_test index-19.2 {
    catchsql {
      BEGIN;
      INSERT INTO t7 VALUES(1);
    }
  } {1 {column a is not unique}}
  do_test index-19.3 {
    catchsql {
      BEGIN;
    }
  } {1 {cannot start a transaction within a transaction}}
  do_test index-19.4 {
    catchsql {
      INSERT INTO t8 VALUES(1);
    }
  } {1 {column a is not unique}}
  do_test index-19.5 {
    catchsql {
      BEGIN;
      COMMIT;
    }
  } {0 {}}
  do_test index-19.6 {
Changes to test/interrupt.test.
76
77
78
79
80
81
82



83
84
85
86
87





88
89
90
91
92
93
94
    COMMIT;
    UPDATE t1 SET b=substr(b,-5,5);
    SELECT count(*) from t1;
  }
} 64
set origsize [file size test.db]
set cksum [db eval {SELECT md5sum(a || b) FROM t1}]



do_test interrupt-2.3 {
  execsql {
    SELECT md5sum(a || b) FROM t1;
  }
} $cksum





ifcapable {explain} {
  do_test interrupt-2.5 {
    set sql {EXPLAIN SELECT max(a,b), a, b FROM t1}
    execsql $sql
    set rc [catch {db eval $sql {sqlite4_interrupt $DB}} msg]
    lappend rc $msg
  } {1 interrupted}







>
>
>





>
>
>
>
>







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
    COMMIT;
    UPDATE t1 SET b=substr(b,-5,5);
    SELECT count(*) from t1;
  }
} 64
set origsize [file size test.db]
set cksum [db eval {SELECT md5sum(a || b) FROM t1}]
ifcapable {vacuum} {
  interrupt_test interrupt-2.2 {VACUUM} {} 100
}
do_test interrupt-2.3 {
  execsql {
    SELECT md5sum(a || b) FROM t1;
  }
} $cksum
ifcapable {vacuum && !default_autovacuum} {
  do_test interrupt-2.4 {
    expr {$::origsize>[file size test.db]}
  } 1
}
ifcapable {explain} {
  do_test interrupt-2.5 {
    set sql {EXPLAIN SELECT max(a,b), a, b FROM t1}
    execsql $sql
    set rc [catch {db eval $sql {sqlite4_interrupt $DB}} msg]
    lappend rc $msg
  } {1 interrupted}
Deleted test/kvstore.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
# 2013 Jul 31
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::testprefix kvstore


do_execsql_test 1.1 { 
  SELECT * FROM sqlite_kvstore ;
  CREATE TABLE t1(x);
} {}

do_execsql_test 1.2 { 
  SELECT quote(key), quote(value) FROM sqlite_kvstore ;
} [list     \
  x'011802' \
  x'052a1e1e035e7461626c657431743102435245415445205441424c45207431287829'
]

do_execsql_test 1.3 { 
  SELECT quote(key), quote(value) FROM sqlite_temp_kvstore ;
} {}


do_execsql_test 2.1 {
  CREATE TABLE t2(x PRIMARY KEY, y UNIQUE);
  INSERT INTO t2 VALUES(1, 2);
  INSERT INTO t2 VALUES(3, 4);
  CREATE INDEX i1 ON t2(y DESC, x DESC);
}
array unset ::data
db eval { SELECT quote(key) AS k, quote(value) AS v FROM sqlite_kvstore } {
  set ::data($k) $v
}
do_execsql_test 2.2 { 
  SELECT quote(key) FROM sqlite_kvstore ORDER BY key DESC;
} [lsort -decreasing [array names ::data]]
do_execsql_test 2.3 { 
  SELECT quote(key) FROM sqlite_kvstore ORDER BY key ASC;
} [lsort -incr [array names ::data]]

set i 0
foreach k [array names ::data] {
  do_execsql_test 2.4.$i "
    SELECT quote(value) FROM sqlite_kvstore WHERE key = $k
  " $::data($k)
  incr i
}

proc key_range {a b} {
  set res [list]
  foreach k [lsort [array names ::data]] {
    if {[string compare $k $a]>=0 && [string compare $k $b]<=0} {
      lappend res $k
    }
  }
  set res
}

set sorted_keys [lsort [array names ::data]]
set nKey [llength $sorted_keys]
for {set i 0} {$i < $nKey} {incr i} {
  for {set i2 $i} {$i2 < $nKey} {incr i2} {
    set k1 [lindex $sorted_keys $i]
    set k2 [lindex $sorted_keys $i2]

    set sql "SELECT quote(key) FROM sqlite_kvstore WHERE key>=$k1 AND key<=$k2"
    set s1 [lsort [key_range $k1 $k2]]
    set s2 [lsort -decr [key_range $k1 $k2]]

    do_execsql_test 2.4.1.$i.$i2.asc " $sql ORDER BY key ASC " $s1
    do_execsql_test 2.4.1.$i.$i2.desc " $sql ORDER BY key DESC " $s2

    set sql "SELECT quote(key) FROM sqlite_kvstore WHERE key>$k1 AND key<=$k2"
    set s1 [lrange [lsort [key_range $k1 $k2]] 1 end]
    set s2 [lsort -decr $s1]

    do_execsql_test 2.4.2.$i.$i2.asc " $sql ORDER BY key ASC " $s1
    do_execsql_test 2.4.2.$i.$i2.desc " $sql ORDER BY key DESC " $s2

    set sql "SELECT quote(key) FROM sqlite_kvstore WHERE key>=$k1 AND key<$k2"
    set s1 [lrange [lsort [key_range $k1 $k2]] 0 end-1]
    set s2 [lsort -decr $s1]

    do_execsql_test 2.4.3.$i.$i2.asc " $sql ORDER BY key ASC " $s1
    do_execsql_test 2.4.3.$i.$i2.desc " $sql ORDER BY key DESC " $s2

    set sql "SELECT quote(key) FROM sqlite_kvstore WHERE key>$k1 AND key<$k2"
    set s1 [lrange [lsort [key_range $k1 $k2]] 1 end-1]
    set s2 [lsort -decr $s1]

    do_execsql_test 2.4.4.$i.$i2.asc " $sql ORDER BY key ASC " $s1
    do_execsql_test 2.4.4.$i.$i2.desc " $sql ORDER BY key DESC " $s2
    do_execsql_test 2.4.4.$i.$i2.asc " $sql ORDER BY key ASC " $s1
    do_execsql_test 2.4.4.$i.$i2.desc " $sql ORDER BY key DESC " $s2

  }
}


 





finish_test

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


















































































































































































































































Changes to test/laststmtchanges.test.
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# changes() changed properly after update into table containing after trigger
do_test laststmtchanges-3.1 {
    catchsql {
        drop trigger r1;
        delete from t2; delete from t2;
        create trigger r1 after update on t1 for each row begin
            insert into t2 values (NULL, changes(), NULL);
            delete from t0 where rowid=1 or rowid=2;
            update t2 set v2=changes();
        end;
        update t1 set k=k;
        select changes();
    }
} {0 1}








|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# changes() changed properly after update into table containing after trigger
do_test laststmtchanges-3.1 {
    catchsql {
        drop trigger r1;
        delete from t2; delete from t2;
        create trigger r1 after update on t1 for each row begin
            insert into t2 values (NULL, changes(), NULL);
            delete from t0 where oid=1 or oid=2;
            update t2 set v2=changes();
        end;
        update t1 set k=k;
        select changes();
    }
} {0 1}

Changes to test/like.test.
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
  execsql {
    SELECT x FROM t1 WHERE x REGEXP '^abc' ORDER BY 1;
  }
} {abc abcd}

# Tests of the MATCH operator
#
# do_test like-2.3 {
#   proc test_match {a b} {
#     return [string match $a $b]
#   }

#   db function match -argcount 2 test_match
#   execsql {
#     SELECT x FROM t1 WHERE x MATCH '*abc*' ORDER BY 1;
#   }

# } {{ABC abc xyz} abc abcd}
# do_test like-2.4 {
#   execsql {
#     SELECT x FROM t1 WHERE x MATCH 'abc*' ORDER BY 1;
#   }

# } {abc abcd}

# For the remaining tests, we need to have the like optimizations
# enabled.
#
ifcapable !like_opt {
  finish_test
  return
} 

# This procedure executes the SQL.  Then it appends to the result the
# "sort" or "nosort" keyword (as in the cksort procedure above) then
# it appends the names of the table and index used.
#
proc queryplan {sql} {
  set ::sqlite_sort_count 0
  set data [execsql $sql]
  if {$::sqlite_sort_count} {set x sort} {set x nosort}
  lappend data $x
  set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
  # puts eqp=$eqp
  foreach {a b c x} $eqp {
    if {[regexp { TABLE (\w+ AS )?(\w+) USING COVERING INDEX (\w+)\y} \
        $x all as tab idx]} {
      lappend data {} $idx
    } elseif {[regexp { TABLE (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \
        $x all as tab idx]} {
      lappend data $tab $idx
    } elseif {[regexp { TABLE (\w+ AS )?(\w+)\y} $x all as tab]} {
      lappend data $tab *
    }
  }
  return $data   
}

# Perform tests on the like optimization.
#
# With no index on t1.x and with case sensitivity turned off, no optimization
# is performed.
#
do_test like-3.1 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {ABC {ABC abc xyz} abc abcd sort t1 *}
do_test like-3.2 {
  set sqlite_like_count
} {12}

# With an index on t1.x and case sensitivity on, optimize completely.
#
do_test like-3.3 {
  set sqlite_like_count 0
  execsql {
    PRAGMA case_sensitive_like=on;
    CREATE INDEX i1 ON t1(x);
  }
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {abc abcd nosort t1 i1}
do_test like-3.4 {
  set sqlite_like_count
} 0

# The LIKE optimization still works when the RHS is a string with no
# wildcard.  Ticket [e090183531fc2747]
#
do_test like-3.4.2 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
  }
} {a nosort t1 i1}
do_test like-3.4.3 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
  }
} {ab nosort t1 i1}
do_test like-3.4.4 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
  }
} {abcd nosort t1 i1}
do_test like-3.4.5 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;
  }
} {nosort t1 i1}


# Partial optimization when the pattern does not end in '%'
#
do_test like-3.5 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;
  }
} {abc nosort t1 i1}
do_test like-3.6 {
  set sqlite_like_count
} 6
do_test like-3.7 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;
  }
} {abcd abd nosort t1 i1}
do_test like-3.8 {
  set sqlite_like_count
} 4
do_test like-3.9 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;
  }
} {abc abcd nosort t1 i1}
do_test like-3.10 {
  set sqlite_like_count
} 6

# No optimization when the pattern begins with a wildcard.
# Note that the index is still used but only for sorting.
#
do_test like-3.11 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;
  }
} {abcd bcd nosort t1 i1}
do_test like-3.12 {
  set sqlite_like_count
} 12

# No optimization for case insensitive LIKE
#
do_test like-3.13 {
  set sqlite_like_count 0
  db eval {PRAGMA case_sensitive_like=off;}
  queryplan {

    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {ABC {ABC abc xyz} abc abcd nosort t1 i1}
do_test like-3.14 {
  set sqlite_like_count
} 12

# No optimization without an index.
#
do_test like-3.15 {
  set sqlite_like_count 0
  db eval {
    PRAGMA case_sensitive_like=on;
    DROP INDEX i1;
  }
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {abc abcd sort t1 *}
do_test like-3.16 {
  set sqlite_like_count
} 12

# No GLOB optimization without an index.
#
do_test like-3.17 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
  }
} {abc abcd sort t1 *}
do_test like-3.18 {
  set sqlite_like_count
} 12

# GLOB is optimized regardless of the case_sensitive_like setting.
#
do_test like-3.19 {
  set sqlite_like_count 0
  db eval {CREATE INDEX i1 ON t1(x);}
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
  }
} {abc abcd nosort t1 i1}
do_test like-3.20 {
  set sqlite_like_count
} 0
do_test like-3.21 {
  set sqlite_like_count 0
  db eval {PRAGMA case_sensitive_like=on;}
  queryplan {

    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
  }
} {abc abcd nosort t1 i1}
do_test like-3.22 {
  set sqlite_like_count
} 0
do_test like-3.23 {
  set sqlite_like_count 0
  db eval {PRAGMA case_sensitive_like=off;}
  queryplan {

    SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;
  }
} {abd acd nosort t1 i1}
do_test like-3.24 {
  set sqlite_like_count
} 6

# GLOB optimization when there is no wildcard.  Ticket [e090183531fc2747]
#
do_test like-3.25 {
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
  }
} {a nosort t1 i1}
do_test like-3.26 {
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
  }
} {abcd nosort t1 i1}
do_test like-3.27 {
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;
  }
} {nosort t1 i1}



# No optimization if the LHS of the LIKE is not a column name or
# if the RHS is not a string.
#
do_test like-4.1 {
  execsql {PRAGMA case_sensitive_like=on}
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {abc abcd nosort t1 i1}
do_test like-4.2 {
  set sqlite_like_count
} 0
do_test like-4.3 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1
  }
} {abc abcd nosort t1 i1}
do_test like-4.4 {
  set sqlite_like_count
} 12
do_test like-4.5 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1
  }
} {abc abcd nosort t1 i1}
do_test like-4.6 {
  set sqlite_like_count
} 12

# Collating sequences on the index disable the LIKE optimization.
# Or if the NOCASE collating sequence is used, the LIKE optimization
# is enabled when case_sensitive_like is OFF.
#
do_test like-5.1 {
  execsql {PRAGMA case_sensitive_like=off}
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {ABC {ABC abc xyz} abc abcd nosort t1 i1}
do_test like-5.2 {
  set sqlite_like_count
} 12
do_test like-5.3 {
  execsql {
    CREATE TABLE t2(x TEXT COLLATE NOCASE);
    INSERT INTO t2 SELECT * FROM t1 ORDER BY rowid;
    CREATE INDEX i2 ON t2(x COLLATE NOCASE);
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {abc ABC {ABC abc xyz} abcd nosort t2 i2}
do_test like-5.4 {
  set sqlite_like_count
} 0
do_test like-5.5 {
  execsql {
    PRAGMA case_sensitive_like=on;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {abc abcd nosort t2 i2}
do_test like-5.6 {
  set sqlite_like_count
} 12
do_test like-5.7 {
  execsql {
    PRAGMA case_sensitive_like=off;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1
  }
} {abc abcd nosort t2 i2}
do_test like-5.8 {
  set sqlite_like_count
} 12
do_test like-5.11 {
  execsql {PRAGMA case_sensitive_like=off}
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'ABC%' ORDER BY 1
  }
} {ABC {ABC abc xyz} abc abcd nosort t1 i1}
do_test like-5.12 {
  set sqlite_like_count
} 12
do_test like-5.13 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
  }
} {abc ABC {ABC abc xyz} abcd nosort t2 i2}
do_test like-5.14 {
  set sqlite_like_count
} 0
do_test like-5.15 {
  execsql {
    PRAGMA case_sensitive_like=on;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
  }
} {ABC {ABC abc xyz} nosort t2 i2}
do_test like-5.16 {
  set sqlite_like_count
} 12
do_test like-5.17 {
  execsql {
    PRAGMA case_sensitive_like=off;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x GLOB 'ABC*' ORDER BY 1
  }
} {ABC {ABC abc xyz} nosort t2 i2}
do_test like-5.18 {
  set sqlite_like_count
} 12

# Boundary case.  The prefix for a LIKE comparison is rounded up
# when constructing the comparison.  Example:  "ab" becomes "ac".
# In other words, the last character is increased by one.







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











|






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












|















|











|




|




|




|









|








|








|












|








<

>


|








|


<
<


|











|












|





<

>


|





<

>


|










|




|




|












|








|








|














|






|






|











|











|









|








|











|











|







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
  execsql {
    SELECT x FROM t1 WHERE x REGEXP '^abc' ORDER BY 1;
  }
} {abc abcd}

# Tests of the MATCH operator
#
do_test like-2.3 {
  proc test_match {a b} {
    return [string match $a $b]

  }
  db function match -argcount 2 test_match
  execsql {
    SELECT x FROM t1 WHERE x MATCH '*abc*' ORDER BY 1;

  }
} {{ABC abc xyz} abc abcd}
do_test like-2.4 {
  execsql {
    SELECT x FROM t1 WHERE x MATCH 'abc*' ORDER BY 1;

  }
} {abc abcd}

# For the remaining tests, we need to have the like optimizations
# enabled.
#
ifcapable !like_opt {
  finish_test
  return
} 

# This procedure executes the SQL.  Then it appends to the result the
# "sort" or "nosort" keyword (as in the cksort procedure above) then
# it appends the ::sqlite_query_plan variable.
#
proc queryplan {sql} {
  set ::sqlite_sort_count 0
  set data [execsql $sql]
  if {$::sqlite_sort_count} {set x sort} {set x nosort}
  lappend data $x













  return [concat $data $::sqlite_query_plan]
}

# Perform tests on the like optimization.
#
# With no index on t1.x and with case sensitivity turned off, no optimization
# is performed.
#
do_test like-3.1 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {ABC {ABC abc xyz} abc abcd sort t1 {}}
do_test like-3.2 {
  set sqlite_like_count
} {12}

# With an index on t1.x and case sensitivity on, optimize completely.
#
do_test like-3.3 {
  set sqlite_like_count 0
  execsql {
    PRAGMA case_sensitive_like=on;
    CREATE INDEX i1 ON t1(x);
  }
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {abc abcd nosort {} i1}
do_test like-3.4 {
  set sqlite_like_count
} 0

# The LIKE optimization still works when the RHS is a string with no
# wildcard.  Ticket [e090183531fc2747]
#
do_test like-3.4.2 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
  }
} {a nosort {} i1}
do_test like-3.4.3 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
  }
} {ab nosort {} i1}
do_test like-3.4.4 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
  }
} {abcd nosort {} i1}
do_test like-3.4.5 {
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;
  }
} {nosort {} i1}


# Partial optimization when the pattern does not end in '%'
#
do_test like-3.5 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;
  }
} {abc nosort {} i1}
do_test like-3.6 {
  set sqlite_like_count
} 6
do_test like-3.7 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;
  }
} {abcd abd nosort {} i1}
do_test like-3.8 {
  set sqlite_like_count
} 4
do_test like-3.9 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;
  }
} {abc abcd nosort {} i1}
do_test like-3.10 {
  set sqlite_like_count
} 6

# No optimization when the pattern begins with a wildcard.
# Note that the index is still used but only for sorting.
#
do_test like-3.11 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;
  }
} {abcd bcd nosort {} i1}
do_test like-3.12 {
  set sqlite_like_count
} 12

# No optimization for case insensitive LIKE
#
do_test like-3.13 {
  set sqlite_like_count 0

  queryplan {
    PRAGMA case_sensitive_like=off;
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {ABC {ABC abc xyz} abc abcd nosort {} i1}
do_test like-3.14 {
  set sqlite_like_count
} 12

# No optimization without an index.
#
do_test like-3.15 {
  set sqlite_like_count 0
  queryplan {
    PRAGMA case_sensitive_like=on;
    DROP INDEX i1;


    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
  }
} {abc abcd sort t1 {}}
do_test like-3.16 {
  set sqlite_like_count
} 12

# No GLOB optimization without an index.
#
do_test like-3.17 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
  }
} {abc abcd sort t1 {}}
do_test like-3.18 {
  set sqlite_like_count
} 12

# GLOB is optimized regardless of the case_sensitive_like setting.
#
do_test like-3.19 {
  set sqlite_like_count 0
  db eval {CREATE INDEX i1 ON t1(x);}
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
  }
} {abc abcd nosort {} i1}
do_test like-3.20 {
  set sqlite_like_count
} 0
do_test like-3.21 {
  set sqlite_like_count 0

  queryplan {
    PRAGMA case_sensitive_like=on;
    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
  }
} {abc abcd nosort {} i1}
do_test like-3.22 {
  set sqlite_like_count
} 0
do_test like-3.23 {
  set sqlite_like_count 0

  queryplan {
    PRAGMA case_sensitive_like=off;
    SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;
  }
} {abd acd nosort {} i1}
do_test like-3.24 {
  set sqlite_like_count
} 6

# GLOB optimization when there is no wildcard.  Ticket [e090183531fc2747]
#
do_test like-3.25 {
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
  }
} {a nosort {} i1}
do_test like-3.26 {
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
  }
} {abcd nosort {} i1}
do_test like-3.27 {
  queryplan {
    SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;
  }
} {nosort {} i1}



# No optimization if the LHS of the LIKE is not a column name or
# if the RHS is not a string.
#
do_test like-4.1 {
  execsql {PRAGMA case_sensitive_like=on}
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {abc abcd nosort {} i1}
do_test like-4.2 {
  set sqlite_like_count
} 0
do_test like-4.3 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1
  }
} {abc abcd nosort {} i1}
do_test like-4.4 {
  set sqlite_like_count
} 12
do_test like-4.5 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1
  }
} {abc abcd nosort {} i1}
do_test like-4.6 {
  set sqlite_like_count
} 12

# Collating sequences on the index disable the LIKE optimization.
# Or if the NOCASE collating sequence is used, the LIKE optimization
# is enabled when case_sensitive_like is OFF.
#
do_test like-5.1 {
  execsql {PRAGMA case_sensitive_like=off}
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {ABC {ABC abc xyz} abc abcd nosort {} i1}
do_test like-5.2 {
  set sqlite_like_count
} 12
do_test like-5.3 {
  execsql {
    CREATE TABLE t2(x TEXT COLLATE NOCASE);
    INSERT INTO t2 SELECT * FROM t1;
    CREATE INDEX i2 ON t2(x COLLATE NOCASE);
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {abc ABC {ABC abc xyz} abcd nosort {} i2}
do_test like-5.4 {
  set sqlite_like_count
} 0
do_test like-5.5 {
  execsql {
    PRAGMA case_sensitive_like=on;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
  }
} {abc abcd nosort {} i2}
do_test like-5.6 {
  set sqlite_like_count
} 12
do_test like-5.7 {
  execsql {
    PRAGMA case_sensitive_like=off;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1
  }
} {abc abcd nosort {} i2}
do_test like-5.8 {
  set sqlite_like_count
} 12
do_test like-5.11 {
  execsql {PRAGMA case_sensitive_like=off}
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t1 WHERE x LIKE 'ABC%' ORDER BY 1
  }
} {ABC {ABC abc xyz} abc abcd nosort {} i1}
do_test like-5.12 {
  set sqlite_like_count
} 12
do_test like-5.13 {
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
  }
} {abc ABC {ABC abc xyz} abcd nosort {} i2}
do_test like-5.14 {
  set sqlite_like_count
} 0
do_test like-5.15 {
  execsql {
    PRAGMA case_sensitive_like=on;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
  }
} {ABC {ABC abc xyz} nosort {} i2}
do_test like-5.16 {
  set sqlite_like_count
} 12
do_test like-5.17 {
  execsql {
    PRAGMA case_sensitive_like=off;
  }
  set sqlite_like_count 0
  queryplan {
    SELECT x FROM t2 WHERE x GLOB 'ABC*' ORDER BY 1
  }
} {ABC {ABC abc xyz} nosort {} i2}
do_test like-5.18 {
  set sqlite_like_count
} 12

# Boundary case.  The prefix for a LIKE comparison is rounded up
# when constructing the comparison.  Example:  "ab" becomes "ac".
# In other words, the last character is increased by one.
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
    INSERT INTO t2 VALUES('zZ-lower-upper');
    INSERT INTO t2 VALUES('Zz-upper-lower');
    INSERT INTO t2 VALUES('zz-lower-lower');
  }
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'zz%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort t2 i2}
do_test like-5.22 {
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'zZ%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort t2 i2}
do_test like-5.23 {
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'Zz%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort t2 i2}
do_test like-5.24 {
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'ZZ%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort t2 i2}
do_test like-5.25 {
  db eval {
    PRAGMA case_sensitive_like=on;
    CREATE TABLE t3(x TEXT);
    CREATE INDEX i3 ON t3(x);
    INSERT INTO t3 VALUES('ZZ-upper-upper');
    INSERT INTO t3 VALUES('zZ-lower-upper');
    INSERT INTO t3 VALUES('Zz-upper-lower');
    INSERT INTO t3 VALUES('zz-lower-lower');
  }
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'zz%';
  }
} {zz-lower-lower nosort t3 i3}
do_test like-5.26 {
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'zZ%';
  }
} {zZ-lower-upper nosort t3 i3}
do_test like-5.27 {
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'Zz%';
  }
} {Zz-upper-lower nosort t3 i3}
do_test like-5.28 {
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'ZZ%';
  }
} {ZZ-upper-upper nosort t3 i3}


# ticket #2407
#
# Make sure the LIKE prefix optimization does not strip off leading
# characters of the like pattern that happen to be quote characters.
#







|




|




|




|













|




|




|




|







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
    INSERT INTO t2 VALUES('zZ-lower-upper');
    INSERT INTO t2 VALUES('Zz-upper-lower');
    INSERT INTO t2 VALUES('zz-lower-lower');
  }
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'zz%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
do_test like-5.22 {
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'zZ%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
do_test like-5.23 {
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'Zz%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
do_test like-5.24 {
  queryplan {
    SELECT x FROM t2 WHERE x LIKE 'ZZ%';
  }
} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
do_test like-5.25 {
  db eval {
    PRAGMA case_sensitive_like=on;
    CREATE TABLE t3(x TEXT);
    CREATE INDEX i3 ON t3(x);
    INSERT INTO t3 VALUES('ZZ-upper-upper');
    INSERT INTO t3 VALUES('zZ-lower-upper');
    INSERT INTO t3 VALUES('Zz-upper-lower');
    INSERT INTO t3 VALUES('zz-lower-lower');
  }
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'zz%';
  }
} {zz-lower-lower nosort {} i3}
do_test like-5.26 {
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'zZ%';
  }
} {zZ-lower-upper nosort {} i3}
do_test like-5.27 {
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'Zz%';
  }
} {Zz-upper-lower nosort {} i3}
do_test like-5.28 {
  queryplan {
    SELECT x FROM t3 WHERE x LIKE 'ZZ%';
  }
} {ZZ-upper-upper nosort {} i3}


# ticket #2407
#
# Make sure the LIKE prefix optimization does not strip off leading
# characters of the like pattern that happen to be quote characters.
#
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
    }]
  } {0 {x hello}}
  ifcapable explain {
    do_test like-9.4.3 {
      set res [sqlite4_exec_hex db {
         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'
      }]
      regexp {SCAN TABLE t2} $res
    } {1}
  }
  do_test like-9.5.1 {
    set res [sqlite4_exec_hex db {
       SELECT x FROM t2 WHERE x LIKE '%fe%25'
    }]
  } {0 {}}
  ifcapable explain {







|
|







658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
    }]
  } {0 {x hello}}
  ifcapable explain {
    do_test like-9.4.3 {
      set res [sqlite4_exec_hex db {
         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'
      }]
      regexp {INDEX i2} $res
    } {0}
  }
  do_test like-9.5.1 {
    set res [sqlite4_exec_hex db {
       SELECT x FROM t2 WHERE x LIKE '%fe%25'
    }]
  } {0 {}}
  ifcapable explain {
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
      SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
  do_test like-10.5 {
    count {
      SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
    }
  } {12 123 scan 2 like 0}
  do_test like-10.6 {
    count {
      SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
  do_test like-10.10 {
    execsql {







|







730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
      SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
  do_test like-10.5 {
    count {
      SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
    }
  } {12 123 scan 3 like 0}
  do_test like-10.6 {
    count {
      SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
  do_test like-10.10 {
    execsql {
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
      SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
  do_test like-10.14 {
    count {
      SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
    }
  } {12 123 scan 2 like 0}
  do_test like-10.15 {
    count {
      SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
}








|







771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
      SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
  do_test like-10.14 {
    count {
      SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
    }
  } {12 123 scan 3 like 0}
  do_test like-10.15 {
    count {
      SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
    }
  } {12 123 scan 5 like 6}
}

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
    INSERT INTO t11 VALUES(10, 'yz','yz');
    INSERT INTO t11 VALUES(11, 'X','X');
    INSERT INTO t11 VALUES(12, 'YZ','YZ');
    SELECT count(*) FROM t11;
  }
} {12}
do_test like-11.1 {
  db eval {PRAGMA case_sensitive_like=OFF;}
  queryplan {

    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
  }
} {abc abcd ABC ABCD nosort t11 *}
do_test like-11.2 {
  db eval {PRAGMA case_sensitive_like=ON;}
  queryplan {

    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
  }
} {abc abcd nosort t11 *}
do_test like-11.3 {
  db eval {
    PRAGMA case_sensitive_like=OFF;
    CREATE INDEX t11b ON t11(b);
  }
  queryplan {
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort t11 t11b}
do_test like-11.4 {
  db eval {PRAGMA case_sensitive_like=ON;}
  queryplan {

    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
  }
} {abc abcd nosort t11 *}
do_test like-11.5 {
  db eval {
    PRAGMA case_sensitive_like=OFF;
    DROP INDEX t11b;
    CREATE INDEX t11bnc ON t11(b COLLATE nocase);
  }
  queryplan {
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort t11 t11bnc}
do_test like-11.6 {
  db eval {CREATE INDEX t11bb ON t11(b COLLATE binary);}
  queryplan {

    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort t11 t11bnc}
do_test like-11.7 {
  db eval {PRAGMA case_sensitive_like=ON;}
  queryplan {

    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd sort t11 t11bb}
do_test like-11.8 {
  db eval {PRAGMA case_sensitive_like=OFF;}
  queryplan {

    SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY +a;
  }
} {abc abcd sort t11 t11bb}
do_test like-11.9 {
  db eval {
    CREATE INDEX t11cnc ON t11(c COLLATE nocase);
    CREATE INDEX t11cb ON t11(c COLLATE binary);
  }
  queryplan {
    SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort t11 t11cnc}
do_test like-11.10 {
  queryplan {
    SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY +a;
  }
} {abc abcd sort t11 t11cb}


finish_test







<

>




<

>




|


<
<


|

<

>




|



<
<


|

<

>


|

<

>


|

<

>


|

|


<
<


|




|



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
    INSERT INTO t11 VALUES(10, 'yz','yz');
    INSERT INTO t11 VALUES(11, 'X','X');
    INSERT INTO t11 VALUES(12, 'YZ','YZ');
    SELECT count(*) FROM t11;
  }
} {12}
do_test like-11.1 {

  queryplan {
    PRAGMA case_sensitive_like=OFF;
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
  }
} {abc abcd ABC ABCD nosort t11 *}
do_test like-11.2 {

  queryplan {
    PRAGMA case_sensitive_like=ON;
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
  }
} {abc abcd nosort t11 *}
do_test like-11.3 {
  queryplan {
    PRAGMA case_sensitive_like=OFF;
    CREATE INDEX t11b ON t11(b);


    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort {} t11b}
do_test like-11.4 {

  queryplan {
    PRAGMA case_sensitive_like=ON;
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
  }
} {abc abcd nosort t11 *}
do_test like-11.5 {
  queryplan {
    PRAGMA case_sensitive_like=OFF;
    DROP INDEX t11b;
    CREATE INDEX t11bnc ON t11(b COLLATE nocase);


    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort {} t11bnc}
do_test like-11.6 {

  queryplan {
    CREATE INDEX t11bb ON t11(b COLLATE binary);
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort {} t11bnc}
do_test like-11.7 {

  queryplan {
    PRAGMA case_sensitive_like=ON;
    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd sort {} t11bb}
do_test like-11.8 {

  queryplan {
    PRAGMA case_sensitive_like=OFF;
    SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY +a;
  }
} {abc abcd sort {} t11bb}
do_test like-11.9 {
  queryplan {
    CREATE INDEX t11cnc ON t11(c COLLATE nocase);
    CREATE INDEX t11cb ON t11(c COLLATE binary);


    SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY +a;
  }
} {abc abcd ABC ABCD sort {} t11cnc}
do_test like-11.10 {
  queryplan {
    SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY +a;
  }
} {abc abcd sort {} t11cb}


finish_test
Changes to test/lsm5.test.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
} {db}
do_test 1.2 {
  db write 1 one
  db write 2 two
  db close
} {}
do_test 1.3 {
  expr [file size test.db] <= (256*1024)
} 1

#-------------------------------------------------------------------------
# Test that if an attempt is made to open a read-write connection to a 
# non-live database that the client does not have permission to write to is
# attempted an error is reported. In order to open a read-write connection 
# to a database, the client requires:







|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
} {db}
do_test 1.2 {
  db write 1 one
  db write 2 two
  db close
} {}
do_test 1.3 {
  expr [file size test.db] < (64*1024)
} 1

#-------------------------------------------------------------------------
# Test that if an attempt is made to open a read-write connection to a 
# non-live database that the client does not have permission to write to is
# attempted an error is reported. In order to open a read-write connection 
# to a database, the client requires:
Changes to test/num.test.
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
  sqlite4_num_isinf [sqlite4_num_from_text inf 3]
} {true}

do_test num-3.1.1 {
  sqlite4_num_to_text [sqlite4_num_add 5 7]
} {12}

foreach {tn a b difference} {
  1   9       3       6
  2   5       12      -7
  3   -9      -10     1
  4   -2      4       -6
  5   -48     -48     0
  6   NaN     4       NaN
  7   95      NaN     NaN
  8   NaN     inf     NaN
  9   inf     inf     NaN
  10  -inf    -inf    NaN
  11  inf     -inf    inf
  12  -inf    955     -inf
  13  -inf    inf     -inf
} {
  do_test num-4.1.$tn {
   sqlite4_num_to_text [sqlite4_num_sub $a $b] 
  } $difference
}
do_test num-4.2.1 {
  sqlite4_num_compare [sqlite4_num_sub 1 1] [sqlite4_num_sub -1 -1]
} {equal}


foreach {tn a b product} {
  1   9       8       72
  2   NaN     inf     NaN
  3   inf     NaN     NaN
  4   inf     0       NaN
  5   inf     -inf    -inf
  6   NaN     0       NaN
  7   NaN     1       NaN
  8   NaN     -9      NaN
  9   NaN     NaN     NaN
} { 
  do_test num-5.1.$tn {
    sqlite4_num_to_text [sqlite4_num_mul $a $b]
  } $product
}

do_test num-6.1.1 {
  sqlite4_num_to_text [sqlite4_num_div 6 5]
} {1.2}
do_test num-6.1.2 {
  sqlite4_num_compare 2 [sqlite4_num_div 2 1]
} {equal}







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




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







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
  sqlite4_num_isinf [sqlite4_num_from_text inf 3]
} {true}

do_test num-3.1.1 {
  sqlite4_num_to_text [sqlite4_num_add 5 7]
} {12}

do_test num-4.1.1 {
  sqlite4_num_to_text [sqlite4_num_sub 9 3]












} {6}
do_test num-4.1.2 {
  sqlite4_num_to_text [sqlite4_num_sub 5 12]

} {-7}
do_test num-4.2.1 {
  sqlite4_num_compare [sqlite4_num_sub 1 1] [sqlite4_num_sub -1 -1]
} {equal}













do_test num-5.1.1 {
  sqlite4_num_to_text [sqlite4_num_mul 9 8]

} {72}

do_test num-6.1.1 {
  sqlite4_num_to_text [sqlite4_num_div 6 5]
} {1.2}
do_test num-6.1.2 {
  sqlite4_num_compare 2 [sqlite4_num_div 2 1]
} {equal}
Changes to test/permutations.test.
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
test_suite "src4" -prefix "" -description {
} -files {
  simple.test simple2.test
  lsm1.test lsm2.test lsm3.test lsm4.test lsm5.test
  csr1.test
  ckpt1.test
  mc1.test
  fts5expr1.test fts5query1.test fts5rnd1.test fts5create.test fts5snippet.test


  alter.test alter3.test alter4.test
  analyze.test analyze3.test analyze4.test analyze5.test 
  analyze6.test analyze7.test analyze8.test
  auth.test auth2.test auth3.test auth4.test
  aggerror.test
  attach.test attach3.test attach4.test
  autoindex1.test
  badutf.test badutf2.test
  between.test
  bigrow.test
  bind.test
  blob.test
  boundary1.test boundary2.test boundary3.test boundary4.test
  capi2.test
  cast.test
  check.test
  coalesce.test 
  collate1.test collate2.test collate3.test collate4.test collate5.test
  collate6.test collate7.test collate8.test collate9.test collateA.test
  collateerr.test
  covidx.test
  conflict.test 
  count.test
  createtab.test
  cse.test
  ctime.test
  date.test
  default.test
  delete.test delete2.test delete3.test
  descidx1.test descidx2.test descidx3.test 
  distinct.test distinctagg.test
  e_createtable.test e_delete.test e_droptrigger.test e_dropview.test
  e_expr.test e_fkey.test e_insert.test e_reindex.test
  e_resolve.test e_select.test e_select2.test e_update.test
  enc.test enc3.test enc4.test
  errmsg.test
  eval.test
  expr.test
  exec.test
  exists.test
  fkey1.test fkey2.test fkey3.test fkey4.test
  func.test func2.test func3.test 
  fuzz.test fuzz2.test 
  in.test in2.test in3.test in4.test
  index.test index2.test index3.test index4.test 
  insert.test insert2.test insert3.test insert5.test
  join.test join2.test join3.test join4.test join5.test join6.test
  keyword1.test
  kvstore.test
  laststmtchanges.test
  limit.test
  like.test like2.test
  main.test
  manydb.test
  misc5.test misc6.test
  misuse.test
  notnull.test
  null.test
  num.test num2.test







|
>

<

|


|

|



|
|
<

<



<
<


<



<
|
<

<
<
<
|
<
|
|
|
|


|
|
|



<
<

<







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
test_suite "src4" -prefix "" -description {
} -files {
  simple.test simple2.test
  lsm1.test lsm2.test lsm3.test lsm4.test lsm5.test
  csr1.test
  ckpt1.test
  mc1.test
  fts5expr1.test fts5query1.test fts5rnd1.test fts5create.test
  fts5snippet.test


  analyze.test analyze3.test analyze4.test analyze5.test 
  analyze6.test analyze7.test
  auth.test auth2.test auth3.test auth4.test
  aggerror.test
  attach.test
  autoindex1.test
  badutf.test
  between.test
  bigrow.test
  bind.test

  boundary1.test boundary4.test

  cast.test

  coalesce.test 
  collate1.test collate2.test collate3.test collate4.test collate5.test
  collate6.test collate7.test collate8.test collate9.test collateA.test


  conflict.test 
  count.test

  cse.test
  ctime.test
  date.test

  delete.test delete2.test

  distinct.test distinctagg.test



  enc.test enc4.test

  exists.test
  e_droptrigger.test e_dropview.test
  e_resolve.test e_dropview.test
  e_select2.test
  fkey1.test fkey2.test fkey3.test fkey4.test
  func.test func2.test func3.test 
  fuzz2.test 
  in.test in4.test
  index2.test index3.test index4.test 
  insert.test insert2.test insert3.test insert5.test
  join.test join2.test join3.test join4.test join5.test join6.test
  keyword1.test


  limit.test

  main.test
  manydb.test
  misc5.test misc6.test
  misuse.test
  notnull.test
  null.test
  num.test num2.test
Changes to test/simple.test.
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
do_execsql_test 38.2 {
  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.3 {
  SELECT * FROM v1;
} {3 4}
do_execsql_test 38.4 {
  DELETE FROM v1 WHERE a = 3;
} 
do_execsql_test 38.5 {
  SELECT * FROM log;
} {4 3}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 39.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);







<
<
<

<
<







693
694
695
696
697
698
699



700


701
702
703
704
705
706
707
do_execsql_test 38.2 {
  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.3 {



  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);
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
  CREATE INDEX joinme_id_int_idx on joinme(id_int);
}

do_catchsql_test 70.2 {
  select * from maintable as m inner join
    joinme as j indexed by joinme_id_text_idx
    on ( m.id  = j.id_int)
} {1 {no query solution}}

do_catchsql_test 70.3 {
  select * from maintable, joinme INDEXED by joinme_id_text_idx
} {1 {no query solution}}

#-------------------------------------------------------------------------
# This is testing that the "phantom" runs feature works.
#
# UPDATE: Said feature was dropped early in development. But the test 
# remains valid.
reset_db







|



|







1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
  CREATE INDEX joinme_id_int_idx on joinme(id_int);
}

do_catchsql_test 70.2 {
  select * from maintable as m inner join
    joinme as j indexed by joinme_id_text_idx
    on ( m.id  = j.id_int)
} {1 {cannot use index: joinme_id_text_idx}}

do_catchsql_test 70.3 {
  select * from maintable, joinme INDEXED by joinme_id_text_idx
} {1 {cannot use index: joinme_id_text_idx}}

#-------------------------------------------------------------------------
# This is testing that the "phantom" runs feature works.
#
# UPDATE: Said feature was dropped early in development. But the test 
# remains valid.
reset_db
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
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
  INSERT INTO t1 VALUES('t1', 't1', 1, 0, 0, x'1802');
  INSERT INTO t1 VALUES('t1', 't1', 1, 1, 1, x'1804');
}

do_execsql_test 80.2 {
  SELECT idx, count(*), sum(length(sample)) FROM t1 GROUP BY idx
} {t1 2 4 t1i1 2 4 t1i2 2 4 t1i3 2 4}

#-------------------------------------------------------------------------
reset_db
do_test 81.1 {
  execsql {
    CREATE TABLE t1(a TEXT);
    INSERT INTO t1 VALUES(5.4e-08);
    SELECT a FROM t1;
  }
} {5.4e-8}

#-------------------------------------------------------------------------
reset_db
do_test 82.1 {
  execsql { CREATE TABLE t1(a TEXT) }
  execsql { SELECT * FROM sqlite_master }
} {table t1 t1 2 {CREATE TABLE t1(a TEXT)}}

do_test 82.2 {
  execsql { DROP TABLE t1 }
  execsql { CREATE TABLE t1(a TEXT) }
  execsql { SELECT * FROM sqlite_master }
} {table t1 t1 2 {CREATE TABLE t1(a TEXT)}}

#-------------------------------------------------------------------------
reset_db
do_test 83.1 {
  execsql { SELECT CAST('2.12e-01ABC' AS INT) }
} {2}
do_test 83.2 {
  execsql { SELECT CAST('   -2.12e-01ABC' AS INT) }
} {-2}
do_test 83.3 {
  execsql { SELECT CAST('45.0' AS NUMERIC) }
} {45}
do_test 83.4 {
  execsql { SELECT CAST(0.0 AS TEXT) }
} {0.0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 84.1 {
  SELECT 1e600 * 1e600 * 0.0;
} {{}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 85.1 {
  CREATE TABLE t1(x INT, y COLLATE NOCASE);
  INSERT INTO t1(x,y) VALUES(2,CAST(x'02' AS TEXT));
  CREATE TABLE t3(x INT, y COLLATE NOCASE);
  INSERT INTO t3 SELECT x, 'abc' || y || 'xyz' FROM t1;
  CREATE INDEX i3 ON t3(y);
  SELECT x FROM t3 WHERE y LIKE 'abcX%';
} {}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 86.0 { 
  SELECT * FROM sqlite_master;
} {}
do_execsql_test 86.1 { 
  CREATE TABLE t1(a PRIMARY KEY, b);
}
do_execsql_test 86.2 { 
  INSERT INTO t1 VALUES(1, 'one');
}
do_execsql_test 86.3 { 
  SELECT * FROM t1;
} {1 one}
do_execsql_test 86.4 { 
  SELECT * FROM t1 WHERE a = 1;
} {1 one}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 87.1 {
  CREATE TABLE t6(a INTEGER PRIMARY KEY, b TEXT);
  CREATE INDEX t6i1 ON t6(b);
} {}
do_eqp_test 87.2 {
  SELECT * FROM t6 ORDER BY b, a;
} {0 0 0 {SCAN TABLE t6 USING INDEX t6i1}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 88.1 {
  CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT);
  CREATE UNIQUE INDEX t8i ON t8(b);
}
do_eqp_test 88.2 {
  SELECT * FROM t8 x ORDER BY x.b, x.a, x.b||x.a
} {0 0 0 {SCAN TABLE t8 AS x USING INDEX t8i}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 89.1 {
  CREATE TABLE t1(a COLLATE NOCASE);
  CREATE INDEX i1 ON t1(a);
}
do_eqp_test 89.2 {
  SELECT * FROM t1 ORDER BY a;
} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}

#-------------------------------------------------------------------------

proc nEphemeral {sql} {
  set nEph 0
  foreach op [execsql "EXPLAIN $sql"] {
    if {$op eq "OpenEphemeral"} {incr nEph}
  }
  set nEph
}

foreach {tn schema} {
  1 {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE t2(x PRIMARY KEY, y);
  }
  2 {
    CREATE TABLE t1(b, a PRIMARY KEY);
    CREATE TABLE t2(x PRIMARY KEY, y);
  }
  3 {
    CREATE TABLE t1(b, a);
    CREATE UNIQUE INDEX i1 ON t1(a) COVERING (b, a);
    CREATE TABLE t2(x PRIMARY KEY, y);
  }
  4 {
    CREATE TABLE t1(b, a);
    CREATE UNIQUE INDEX i1 ON t1(a) COVERING (a, b);
    CREATE TABLE t2(y, x PRIMARY KEY);
  }
} {
  reset_db

  do_execsql_test 90.$tn.0 $schema

  do_execsql_test 90.$tn.1 {
    INSERT INTO t2(x, y) VALUES(1, 'one');
    INSERT INTO t2(x, y) VALUES(2, 'two');
    INSERT INTO t2(x, y) VALUES(3, 'three');
    INSERT INTO t2(x, y) VALUES(4, 'four');
    INSERT INTO t2(x, y) VALUES(5, 'five');
    INSERT INTO t2(x, y) VALUES(6, 'six');

    INSERT INTO t1(a, b) VALUES(2, 'two');
    INSERT INTO t1(a, b) VALUES(3, 'three');
    INSERT INTO t1(a, b) VALUES(5, 'five');
  }

  do_execsql_test 90.$tn.2 {
    SELECT y FROM t2 WHERE x IN (SELECT a FROM t1);
  } {two three five}

  do_test 90.$tn.3 {
    nEphemeral "SELECT y FROM t2 WHERE x IN (SELECT a FROM t1)"
  } 0
}


finish_test









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


1555
1556
1557
1558
1559
1560
1561
1562
































































































































































1563
1564
  INSERT INTO t1 VALUES('t1', 't1', 1, 0, 0, x'1802');
  INSERT INTO t1 VALUES('t1', 't1', 1, 1, 1, x'1804');
}

do_execsql_test 80.2 {
  SELECT idx, count(*), sum(length(sample)) FROM t1 GROUP BY idx
} {t1 2 4 t1i1 2 4 t1i2 2 4 t1i3 2 4}

































































































































































finish_test

Changes to test/subquery.test.
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  execsql {
    CREATE INDEX t4i ON t4(x);
    SELECT * FROM t4 WHERE x IN (SELECT a FROM t3);
  }
} {10.0}
do_test subquery-2.5.3.2 {
  # Verify that the t4i index was not used in the previous query
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t4 WHERE x IN (SELECT a FROM t3);
  }
} {/SCAN TABLE t4/}
do_test subquery-2.5.4 {
  execsql {
    DROP TABLE t3;
    DROP TABLE t4;
  }
} {}








|
<
<
<
|







237
238
239
240
241
242
243
244



245
246
247
248
249
250
251
252
  execsql {
    CREATE INDEX t4i ON t4(x);
    SELECT * FROM t4 WHERE x IN (SELECT a FROM t3);
  }
} {10.0}
do_test subquery-2.5.3.2 {
  # Verify that the t4i index was not used in the previous query
  set ::sqlite_query_plan



} {t4 {}}
do_test subquery-2.5.4 {
  execsql {
    DROP TABLE t3;
    DROP TABLE t4;
  }
} {}

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
} {1 one 2 two}
do_test subquery-3.3.5 {
  execsql {
    SELECT a, (SELECT count(*) FROM t2 WHERE a=c) FROM t1;
  }
} {1 1 2 1}


#------------------------------------------------------------------
# These tests - subquery-4.* - use the TCL statement cache to try 
# and expose bugs to do with re-using statements that have been 
# passed to sqlite4_reset().
#
# One problem was that VDBE memory cells were not being initialized
# to NULL on the second and subsequent executions.
#
do_test subquery-4.1.1 {
  execsql {
    SELECT (SELECT a FROM t1);
  }
} {1}







<





|







327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342
343
344
345
346
} {1 one 2 two}
do_test subquery-3.3.5 {
  execsql {
    SELECT a, (SELECT count(*) FROM t2 WHERE a=c) FROM t1;
  }
} {1 1 2 1}


#------------------------------------------------------------------
# These tests - subquery-4.* - use the TCL statement cache to try 
# and expose bugs to do with re-using statements that have been 
# passed to sqlite4_reset().
#
# One problem was that VDBE memory cells were not being initialised
# to NULL on the second and subsequent executions.
#
do_test subquery-4.1.1 {
  execsql {
    SELECT (SELECT a FROM t1);
  }
} {1}
Changes to test/test_main.c.
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
  Tcl_Interp *interp;
  Tcl_Obj *pNeeded;
  Tcl_Obj *pDel;
};
typedef struct TestNeededX TestNeededX;

static void testCollationNeeded(void *pCtx, sqlite4 *db, const char *zReq){
  TestNeededX *p = (TestNeededX *)pCtx;
  Tcl_Obj *pScript;
  int rc;

  pScript = Tcl_DuplicateObj(p->pNeeded);
  Tcl_IncrRefCount(pScript);
  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zReq, -1));
  rc = Tcl_EvalObjEx(p->interp, pScript, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL);







|







1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
  Tcl_Interp *interp;
  Tcl_Obj *pNeeded;
  Tcl_Obj *pDel;
};
typedef struct TestNeededX TestNeededX;

static void testCollationNeeded(void *pCtx, sqlite4 *db, const char *zReq){
  TestNeededX *p = (TestCollationX *)pCtx;
  Tcl_Obj *pScript;
  int rc;

  pScript = Tcl_DuplicateObj(p->pNeeded);
  Tcl_IncrRefCount(pScript);
  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zReq, -1));
  rc = Tcl_EvalObjEx(p->interp, pScript, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL);
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
  rc = sqlite4_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &nUsed : 0);
  Tcl_ResetResult(interp);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  if( objc>=5 ){
    const char *zTail = &zSql[nUsed];
    int nTail = -1;
    if( bytes>=0 ){
      nTail = (bytes - nUsed);
      if( nTail>strlen(zTail) ) nTail = strlen(zTail);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, nTail), 0);
  }
  if( rc!=SQLITE4_OK ){
    assert( pStmt==0 );
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, sqlite4_errmsg(db), 0);







|
<







2921
2922
2923
2924
2925
2926
2927
2928

2929
2930
2931
2932
2933
2934
2935
  rc = sqlite4_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &nUsed : 0);
  Tcl_ResetResult(interp);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  if( objc>=5 ){
    const char *zTail = &zSql[nUsed];
    int nTail = -1;
    if( bytes>=0 ){
      nTail = bytes - nUsed;

    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, nTail), 0);
  }
  if( rc!=SQLITE4_OK ){
    assert( pStmt==0 );
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, sqlite4_errmsg(db), 0);
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
    }
    return TCL_ERROR;
  }
  sqlite4_test_control(SQLITE4_TESTCTRL_OPTIMIZATIONS, db, mask);
  return TCL_OK;
}

/*
** Usage: sqlite4_column_text STMT column
**
** Usage: sqlite4_column_decltype STMT column
**
** Usage: sqlite4_column_name STMT column
*/
static int test_stmt_utf16(
  void * clientData,     /* Pointer to SQLite API function to be invoked */
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#ifndef SQLITE4_OMIT_UTF16
  sqlite4_stmt *pStmt;
  int col;
  Tcl_Obj *pRet;
  const void *zName16;
  const void *(*xFunc)(sqlite4_stmt*, int, int*);
  int dummy;

  xFunc = (const void *(*)(sqlite4_stmt*, int, int*))clientData;
  if( objc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
       Tcl_GetString(objv[0]), " STMT column", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;

  zName16 = xFunc(pStmt, col, &dummy);
  if( zName16 ){
    int n;
    const char *z = zName16;
    for(n=0; z[n] || z[n+1]; n+=2){}
    pRet = Tcl_NewByteArrayObj(zName16, n+2);
    Tcl_SetObjResult(interp, pRet);
  }
#endif /* SQLITE4_OMIT_UTF16 */

  return TCL_OK;
}

void sqlite4TestInit(Tcl_Interp *interp){
  Sqlitetest_auth_init(interp);
  Sqlitetest_num_init(interp);
  Sqlitetest_func_Init(interp);
}

/*







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







4098
4099
4100
4101
4102
4103
4104












































4105
4106
4107
4108
4109
4110
4111
    }
    return TCL_ERROR;
  }
  sqlite4_test_control(SQLITE4_TESTCTRL_OPTIMIZATIONS, db, mask);
  return TCL_OK;
}













































void sqlite4TestInit(Tcl_Interp *interp){
  Sqlitetest_auth_init(interp);
  Sqlitetest_num_init(interp);
  Sqlitetest_func_Init(interp);
}

/*
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
#endif
#ifdef SQLITE4_ENABLE_COLUMN_METADATA
{ "sqlite4_column_database_name",test_stmt_utf8,(void*)sqlite4_column_database_name},
{ "sqlite4_column_table_name",test_stmt_utf8,(void*)sqlite4_column_table_name},
{ "sqlite4_column_origin_name",test_stmt_utf8,(void*)sqlite4_column_origin_name},
#endif

#ifndef SQLITE4_OMIT_UTF16
  { "sqlite4_column_text16",  test_stmt_utf16, (void*)sqlite4_column_text16},
#endif

     { "sqlite4_create_collation",   test_create_collation, 0 },
     { "sqlite4_collation_needed",   test_collation_needed, 0 },
     { "sqlite4_profile",            test_profile, 0 },
     { "sqlite4_trace",              test_trace, 0 },
     { "working_64bit_int",          working_64bit_int,   0   },
     { "sqlite4_create_function_v2", test_create_function_v2, 0 },








<
<
<
<







4222
4223
4224
4225
4226
4227
4228




4229
4230
4231
4232
4233
4234
4235
#endif
#ifdef SQLITE4_ENABLE_COLUMN_METADATA
{ "sqlite4_column_database_name",test_stmt_utf8,(void*)sqlite4_column_database_name},
{ "sqlite4_column_table_name",test_stmt_utf8,(void*)sqlite4_column_table_name},
{ "sqlite4_column_origin_name",test_stmt_utf8,(void*)sqlite4_column_origin_name},
#endif





     { "sqlite4_create_collation",   test_create_collation, 0 },
     { "sqlite4_collation_needed",   test_collation_needed, 0 },
     { "sqlite4_profile",            test_profile, 0 },
     { "sqlite4_trace",              test_trace, 0 },
     { "working_64bit_int",          working_64bit_int,   0   },
     { "sqlite4_create_function_v2", test_create_function_v2, 0 },

4310
4311
4312
4313
4314
4315
4316


4317
4318
4319
4320
4321
4322
4323
  extern int sqlite4_os_type;
#endif
#ifdef SQLITE4_DEBUG
  extern int sqlite4WhereTrace;
  extern int sqlite4OSTrace;
#endif
#ifdef SQLITE4_TEST


#ifdef SQLITE4_ENABLE_FTS3
  extern int sqlite4_fts3_enable_parentheses;
#endif
#endif

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);







>
>







4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
  extern int sqlite4_os_type;
#endif
#ifdef SQLITE4_DEBUG
  extern int sqlite4WhereTrace;
  extern int sqlite4OSTrace;
#endif
#ifdef SQLITE4_TEST
  extern char sqlite4_query_plan[];
  static char *query_plan = sqlite4_query_plan;
#ifdef SQLITE4_ENABLE_FTS3
  extern int sqlite4_fts3_enable_parentheses;
#endif
#endif

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
4347
4348
4349
4350
4351
4352
4353




4354
4355
4356
4357
4358
4359
4360
#endif
  Tcl_LinkVar(interp, "sqlite4_xferopt_count",
      (char*)&sqlite4_xferopt_count, TCL_LINK_INT);
#if SQLITE4_OS_WIN
  Tcl_LinkVar(interp, "sqlite_os_type",
      (char*)&sqlite4_os_type, TCL_LINK_INT);
#endif




#ifdef SQLITE4_DEBUG
  Tcl_LinkVar(interp, "sqlite_where_trace",
      (char*)&sqlite4WhereTrace, TCL_LINK_INT);
#endif
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",







>
>
>
>







4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
#endif
  Tcl_LinkVar(interp, "sqlite4_xferopt_count",
      (char*)&sqlite4_xferopt_count, TCL_LINK_INT);
#if SQLITE4_OS_WIN
  Tcl_LinkVar(interp, "sqlite_os_type",
      (char*)&sqlite4_os_type, TCL_LINK_INT);
#endif
#ifdef SQLITE4_TEST
  Tcl_LinkVar(interp, "sqlite_query_plan",
      (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
#endif
#ifdef SQLITE4_DEBUG
  Tcl_LinkVar(interp, "sqlite_where_trace",
      (char*)&sqlite4WhereTrace, TCL_LINK_INT);
#endif
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",
Changes to test/test_mem.c.
11
12
13
14
15
16
17


18
19
20
21
22
23
24
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>

#include "sqliteInt.h"
#include "testInt.h"



#if defined(__GLIBC__)
  extern int backtrace(void**,int);
  extern void backtrace_symbols_fd(void*const*,int,int);
# define TM_BACKTRACE 12
#else
# define backtrace(A,B) 1







>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>

#include "sqliteInt.h"
#include "testInt.h"

#define MIN(x,y) ((x)<(y) ? (x) : (y))

#if defined(__GLIBC__)
  extern int backtrace(void**,int);
  extern void backtrace_symbols_fd(void*const*,int,int);
# define TM_BACKTRACE 12
#else
# define backtrace(A,B) 1
Changes to test/tester.tcl.
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

  if {![info exists ::G(match)] || [string match $::G(match) $name]} {
    if {[catch {uplevel #0 "$cmd;\n"} result]} {
      puts "\nError: $result"
      fail_test $name
    } else {
      if {[regexp {^~?/.*/$} $expected]} {
        # "expected" is of the form "/PATTERN/" then the result if correct if
        # regular expression PATTERN matches the result.  "~/PATTERN/" means
        # the regular expression must not match.
        if {[string index $expected 0]=="~"} {
          set re [string map {# {[-0-9.]+}} [string range $expected 2 end-1]]
          set ok [expr {![regexp $re $result]}]
        } else {
          set re [string map {# {[-0-9.]+}} [string range $expected 1 end-1]]
          set ok [regexp $re $result]
        }
      } elseif {[regexp {^~?\*.*\*$} $expected]} {
        # "expected" is of the form "*GLOB*" then the result if correct if
        # glob pattern GLOB matches the result.  "~/GLOB/" means
        # the glob must not match.
        if {[string index $expected 0]=="~"} {
          set e [string range $expected 1 end]
          set ok [expr {![string match $e $result]}]
        } else {
          set ok [string match $expected $result]
        }
      } else {
        set ok [expr {[string compare $result $expected]==0}]
      }
      if {!$ok} {
        # if {![info exists ::testprefix] || $::testprefix eq ""} {
        #   error "no test prefix"
        # }







<
<
<







<
<
<
<
<
<
<
<
<
<







491
492
493
494
495
496
497



498
499
500
501
502
503
504










505
506
507
508
509
510
511

  if {![info exists ::G(match)] || [string match $::G(match) $name]} {
    if {[catch {uplevel #0 "$cmd;\n"} result]} {
      puts "\nError: $result"
      fail_test $name
    } else {
      if {[regexp {^~?/.*/$} $expected]} {



        if {[string index $expected 0]=="~"} {
          set re [string map {# {[-0-9.]+}} [string range $expected 2 end-1]]
          set ok [expr {![regexp $re $result]}]
        } else {
          set re [string map {# {[-0-9.]+}} [string range $expected 1 end-1]]
          set ok [regexp $re $result]
        }










      } else {
        set ok [expr {[string compare $result $expected]==0}]
      }
      if {!$ok} {
        # if {![info exists ::testprefix] || $::testprefix eq ""} {
        #   error "no test prefix"
        # }
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407

# Drop all tables in database [db]
proc drop_all_tables {{db db}} {
  ifcapable trigger&&foreignkey {
    set pk [$db one "PRAGMA foreign_keys"]
    $db eval "PRAGMA foreign_keys = OFF"
  }
  foreach {idx name} [db eval {PRAGMA database_list}] {
    if {$idx==1} {
      set master sqlite_temp_master
    } else {
      set master $name.sqlite_master
    }
    foreach {t type} [$db eval "
      SELECT name, type FROM $master







|







1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394

# Drop all tables in database [db]
proc drop_all_tables {{db db}} {
  ifcapable trigger&&foreignkey {
    set pk [$db one "PRAGMA foreign_keys"]
    $db eval "PRAGMA foreign_keys = OFF"
  }
  foreach {idx name file} [db eval {PRAGMA database_list}] {
    if {$idx==1} {
      set master sqlite_temp_master
    } else {
      set master $name.sqlite_master
    }
    foreach {t type} [$db eval "
      SELECT name, type FROM $master
Changes to test/tkt3442.test.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# These tests perform an EXPLAIN QUERY PLAN on both versions of the 
# SELECT referenced in ticket #3442 (both '5000' and "5000") 
# and verify that the query plan is the same.
#
ifcapable explain {
  do_test tkt3442-1.2 {
    EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
}


# Some extra tests testing other permutations of 5000.
#
ifcapable explain {
  do_test tkt3442-1.4 {
    EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
}
do_test tkt3442-1.5 {
  catchsql {
    SELECT node FROM listhash WHERE id=[5000] LIMIT 1;
  }
} {1 {no such column: 5000}}








|








|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# These tests perform an EXPLAIN QUERY PLAN on both versions of the 
# SELECT referenced in ticket #3442 (both '5000' and "5000") 
# and verify that the query plan is the same.
#
ifcapable explain {
  do_test tkt3442-1.2 {
    EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?) (~1 rows)}}
}


# Some extra tests testing other permutations of 5000.
#
ifcapable explain {
  do_test tkt3442-1.4 {
    EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?) (~1 rows)}}
}
do_test tkt3442-1.5 {
  catchsql {
    SELECT node FROM listhash WHERE id=[5000] LIMIT 1;
  }
} {1 {no such column: 5000}}

Changes to test/where.test.
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
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. By verifing that the KVWrap layer


# xNext/xPrev/xSeek count is small we can be assured that indices are 
# being used properly.
#
do_test where-1.1.1 {
  count {SELECT x, y, w FROM t1 WHERE w=10}
} {3 121 10 3}
do_eqp_test where-1.1.2 {
  SELECT x, y, w FROM t1 WHERE w=10
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
do_test where-1.1.3 {
  db status step
} {0}
do_test where-1.1.4 {
  db eval {SELECT x, y, w FROM t1 WHERE +w=10}
} {3 121 10}
do_test where-1.1.5 {
  db status step
} {99}
do_eqp_test where-1.1.6 {
  SELECT x, y, w FROM t1 WHERE +w=10
} {*SCAN TABLE t1*}
do_test where-1.1.7 {
  count {SELECT x, y, w AS abc FROM t1 WHERE abc=10}
} {3 121 10 3}
do_eqp_test where-1.1.8 {
  SELECT x, y, w AS abc FROM t1 WHERE abc=10
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
do_test where-1.1.9 {
  db status step
} {0}
do_test where-1.2.1 {
  count {SELECT x, y, w FROM t1 WHERE w=11}
} {3 144 11 3}
do_test where-1.2.2 {
  count {SELECT x, y, w AS abc FROM t1 WHERE abc=11}
} {3 144 11 3}
do_test where-1.3.1 {
  count {SELECT x, y, w AS abc FROM t1 WHERE 11=w}
} {3 144 11 3}
do_test where-1.3.2 {
  count {SELECT x, y, w AS abc FROM t1 WHERE 11=abc}
} {3 144 11 3}
do_test where-1.4.1 {
  count {SELECT w, x, y FROM t1 WHERE 11=w AND x>2}
} {11 3 144 3}
do_eqp_test where-1.4.2 {
  SELECT w, x, y FROM t1 WHERE 11=w AND x>2
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
do_test where-1.4.3 {
  count {SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2}
} {11 3 144 3}
do_eqp_test where-1.4.4 {
  SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
do_test where-1.5 {
  count {SELECT x, y FROM t1 WHERE y<200 AND w=11 AND x>2}
} {3 144 3}
do_eqp_test where-1.5.2 {
  SELECT x, y FROM t1 WHERE y<200 AND w=11 AND x>2
} {*SEARCH TABLE t1 USING INDEX i1w (w=?)*}
do_test where-1.6 {
  count {SELECT x, y FROM t1 WHERE y<200 AND x>2 AND w=11}
} {3 144 3}
do_test where-1.7 {
  count {SELECT x, y FROM t1 WHERE w=11 AND y<200 AND x>2}
} {3 144 3}
do_test where-1.8 {
  count {SELECT x, y FROM t1 WHERE w>10 AND y=144 AND x=3}
} {3 144 3}
do_eqp_test where-1.8.2 {
  SELECT x, y FROM t1 WHERE w>10 AND y=144 AND x=3
} {*SEARCH TABLE t1 USING INDEX i1xy (x=? AND y=?)*}
do_eqp_test where-1.8.3 {
  SELECT x, y FROM t1 WHERE y=144 AND x=3

} {*SEARCH TABLE t1 USING INDEX i1xy (x=? AND y=?)*}
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 {
  count {SELECT x, y FROM t1 WHERE x=3 AND y=100 AND w<10}
} {3 100 3}


# New for SQLite version 2.1: Verify that that inequality constraints
# are used correctly.
#
do_test where-1.12 {
  count {SELECT w FROM t1 WHERE x=3 AND y<100}
} {8 3}







|
>
>
|
<




|
|
|









|
|
|



|
|
|


















|
|
|



|
|
|



|
|
|









|
|
|
|
|
>
|









<







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
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.

#
do_test where-1.1.1 {
  count {SELECT x, y, w FROM t1 WHERE w=10}
} {3 121 10 3}
do_test where-1.1.2 {
  set sqlite_query_plan
} {t1 i1w}
do_test where-1.1.3 {
  db status step
} {0}
do_test where-1.1.4 {
  db eval {SELECT x, y, w FROM t1 WHERE +w=10}
} {3 121 10}
do_test where-1.1.5 {
  db status step
} {99}
do_test where-1.1.6 {
  set sqlite_query_plan
} {t1 {}}
do_test where-1.1.7 {
  count {SELECT x, y, w AS abc FROM t1 WHERE abc=10}
} {3 121 10 3}
do_test where-1.1.8 {
  set sqlite_query_plan
} {t1 i1w}
do_test where-1.1.9 {
  db status step
} {0}
do_test where-1.2.1 {
  count {SELECT x, y, w FROM t1 WHERE w=11}
} {3 144 11 3}
do_test where-1.2.2 {
  count {SELECT x, y, w AS abc FROM t1 WHERE abc=11}
} {3 144 11 3}
do_test where-1.3.1 {
  count {SELECT x, y, w AS abc FROM t1 WHERE 11=w}
} {3 144 11 3}
do_test where-1.3.2 {
  count {SELECT x, y, w AS abc FROM t1 WHERE 11=abc}
} {3 144 11 3}
do_test where-1.4.1 {
  count {SELECT w, x, y FROM t1 WHERE 11=w AND x>2}
} {11 3 144 3}
do_test where-1.4.2 {
  set sqlite_query_plan
} {t1 i1w}
do_test where-1.4.3 {
  count {SELECT w AS a, x AS b, y FROM t1 WHERE 11=a AND b>2}
} {11 3 144 3}
do_test where-1.4.4 {
  set sqlite_query_plan
} {t1 i1w}
do_test where-1.5 {
  count {SELECT x, y FROM t1 WHERE y<200 AND w=11 AND x>2}
} {3 144 3}
do_test where-1.5.2 {
  set sqlite_query_plan
} {t1 i1w}
do_test where-1.6 {
  count {SELECT x, y FROM t1 WHERE y<200 AND x>2 AND w=11}
} {3 144 3}
do_test where-1.7 {
  count {SELECT x, y FROM t1 WHERE w=11 AND y<200 AND x>2}
} {3 144 3}
do_test where-1.8 {
  count {SELECT x, y FROM t1 WHERE w>10 AND y=144 AND x=3}
} {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 {
  count {SELECT x, y FROM t1 WHERE x=3 AND y=100 AND w<10}
} {3 100 3}


# New for SQLite version 2.1: Verify that that inequality constraints
# are used correctly.
#
do_test where-1.12 {
  count {SELECT w FROM t1 WHERE x=3 AND y<100}
} {8 3}
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# using an index rather than by sorting.
#
do_test where-6.1 {
  execsql {
    CREATE TABLE t3(a,b,c);
    CREATE INDEX t3a ON t3(a);
    CREATE INDEX t3bc ON t3(b,c);
    CREATE INDEX t3acb ON t3(a,c,b) COVERING(a,b,c);
    INSERT INTO t3 SELECT w, 101-w, y FROM t1;
    SELECT count(*), sum(a), sum(b), sum(c) FROM t3;
  }
} {100 5050 5050 348550}
do_test where-6.2 {
  cksort {
    SELECT * FROM t3 ORDER BY a LIMIT 3







|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# using an index rather than by sorting.
#
do_test where-6.1 {
  execsql {
    CREATE TABLE t3(a,b,c);
    CREATE INDEX t3a ON t3(a);
    CREATE INDEX t3bc ON t3(b,c);
    CREATE INDEX t3acb ON t3(a,c,b);
    INSERT INTO t3 SELECT w, 101-w, y FROM t1;
    SELECT count(*), sum(a), sum(b), sum(c) FROM t3;
  }
} {100 5050 5050 348550}
do_test where-6.2 {
  cksort {
    SELECT * FROM t3 ORDER BY a LIMIT 3
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
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 nosort}
}
do_test where-6.9.1 {
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.1.1 {







>
>



|






|







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
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}
}
do_test where-6.9.1 {
  cksort {
    SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a LIMIT 3
  }
} {1 100 4 nosort}
do_test where-6.9.1.1 {
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
    CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT UNIQUE);
    INSERT INTO t8 VALUES(1,'one');
    INSERT INTO t8 VALUES(4,'four');
  }
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b
  } 
} {1/4 1/1 4/4 4/1 nosort}
do_test where-14.2 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b DESC
  } 
} {1/1 1/4 4/1 4/4 nosort}
do_test where-14.3 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b
  } 
} {1/1 1/4 4/1 4/4 nosort}
do_test where-14.4 {
  cksort {







|




|







1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
    CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT UNIQUE);
    INSERT INTO t8 VALUES(1,'one');
    INSERT INTO t8 VALUES(4,'four');
  }
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b
  } 
} {1/4 1/1 4/4 4/1 sort}
do_test where-14.2 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b DESC
  } 
} {1/1 1/4 4/1 4/4 sort}
do_test where-14.3 {
  cksort {
    SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b
  } 
} {1/1 1/4 4/1 4/4 nosort}
do_test where-14.4 {
  cksort {
Changes to test/where7.test.
23328
23329
23330
23331
23332
23333
23334
23335
23336
23337
23338
23339
23340
23341
23342
23343
23344
23345
23346
23347
23348
  );
  CREATE INDEX t302_c3 on t302(c3);
  CREATE INDEX t302_c8_c3 on t302(c8, c3);
  CREATE INDEX t302_c5 on t302(c5);
  
  EXPLAIN QUERY PLAN
  SELECT t302.c1 
    FROM t302 JOIN t301 ON t302.c8 = +t301.c8
    WHERE t302.c2 = 19571
      AND t302.c3 > 1287603136
      AND (t301.c4 = 1407449685622784
           OR t301.c8 = 1407424651264000)
   ORDER BY t302.c5 LIMIT 200;
} {
  0 0 1 {SEARCH TABLE t301 USING INDEX t301_c4 (c4=?)}
  0 0 1 {SEARCH TABLE t301 USING PRIMARY KEY (c8=?)}
  0 1 0 {SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)}
  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}

finish_test







|






|
|
|




23328
23329
23330
23331
23332
23333
23334
23335
23336
23337
23338
23339
23340
23341
23342
23343
23344
23345
23346
23347
23348
  );
  CREATE INDEX t302_c3 on t302(c3);
  CREATE INDEX t302_c8_c3 on t302(c8, c3);
  CREATE INDEX t302_c5 on t302(c5);
  
  EXPLAIN QUERY PLAN
  SELECT t302.c1 
    FROM t302 JOIN t301 ON t302.c8 = t301.c8
    WHERE t302.c2 = 19571
      AND t302.c3 > 1287603136
      AND (t301.c4 = 1407449685622784
           OR t301.c8 = 1407424651264000)
   ORDER BY t302.c5 LIMIT 200;
} {
  0 0 1 {SEARCH TABLE t301 USING INDEX t301_c4 (c4=?) (~5 rows)} 
  0 0 1 {SEARCH TABLE t301 USING PRIMARY KEY (c8=?) (~1 rows)} 
  0 1 0 {SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?) (~2 rows)} 
  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}

finish_test
Changes to test/where8.test.
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  }
} {2 2 3 3 0 0}

do_test where8-3.5 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a = 2 OR a = 3) AND (d = a OR e = 'sixteen')
  }
} {2 2 3 3 2 4 3 4 0 0}

do_test where8-3.6 {
  # The first part of the WHERE clause in this query, (a=2 OR a=3) is
  # transformed into "a IN (2, 3)". This is why the sort is required.
  #
  execsql_status {
    SELECT a, d 







|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  }
} {2 2 3 3 0 0}

do_test where8-3.5 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a = 2 OR a = 3) AND (d = a OR e = 'sixteen')
  }
} {2 2 2 4 3 3 3 4 0 0}

do_test where8-3.6 {
  # The first part of the WHERE clause in this query, (a=2 OR a=3) is
  # transformed into "a IN (2, 3)". This is why the sort is required.
  #
  execsql_status {
    SELECT a, d 
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
  # The "OR c = 'IX'" term forces a linear scan.
  execsql_status2 {
    SELECT a, d 
    FROM t1, t2 
    WHERE (a = 2 OR b = 'three' OR c = 'IX') AND (d = a OR e = 'sixteen')
    ORDER BY t1.rowid
  }
} {2 2 2 4 3 3 3 4 9 9 9 4 9 0 seek=13 step=16}
do_test where8-3.10 {
  execsql_status {
    SELECT d FROM t2 WHERE e IS NULL OR e = 'four'
  }
} {1 3 5 10 2 0 0}

do_test where8-3.11 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a=d OR b=e) AND a<5 ORDER BY a
  }
} {1 1 2 2 3 3 4 2 4 4 0 0}
do_test where8-3.12 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a=d OR b=e) AND +a<5 ORDER BY a
  }
} {1 1 2 2 3 3 4 2 4 4 9 0}
do_test where8-3.13 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a=d OR b=e) AND +a<5
  }
} {1 1 2 2 3 3 4 2 4 4 9 0}

do_test where8-3.14 {







|















|







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
  # The "OR c = 'IX'" term forces a linear scan.
  execsql_status2 {
    SELECT a, d 
    FROM t1, t2 
    WHERE (a = 2 OR b = 'three' OR c = 'IX') AND (d = a OR e = 'sixteen')
    ORDER BY t1.rowid
  }
} {2 2 2 4 3 3 3 4 9 9 9 4 0 0 seek=13 step=16}
do_test where8-3.10 {
  execsql_status {
    SELECT d FROM t2 WHERE e IS NULL OR e = 'four'
  }
} {1 3 5 10 2 0 0}

do_test where8-3.11 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a=d OR b=e) AND a<5 ORDER BY a
  }
} {1 1 2 2 3 3 4 2 4 4 0 0}
do_test where8-3.12 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a=d OR b=e) AND +a<5 ORDER BY a
  }
} {1 1 2 2 3 3 4 2 4 4 0 0}
do_test where8-3.13 {
  execsql_status {
    SELECT a, d FROM t1, t2 WHERE (a=d OR b=e) AND +a<5
  }
} {1 1 2 2 3 3 4 2 4 4 9 0}

do_test where8-3.14 {
Changes to tool/mkkeywordhash.c.
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  { "CAST",             "TK_CAST",         CAST                   },
  { "CHECK",            "TK_CHECK",        ALWAYS                 },
  { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
  { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
  { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
  { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },
  { "COVERING",         "TK_COVERING",     ALWAYS                 },
  { "CREATE",           "TK_CREATE",       ALWAYS                 },
  { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
  { "DATABASE",         "TK_DATABASE",     ATTACH                 },
  { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },







<







158
159
160
161
162
163
164

165
166
167
168
169
170
171
  { "CAST",             "TK_CAST",         CAST                   },
  { "CHECK",            "TK_CHECK",        ALWAYS                 },
  { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
  { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
  { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
  { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
  { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },

  { "CREATE",           "TK_CREATE",       ALWAYS                 },
  { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
  { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
  { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
  { "DATABASE",         "TK_DATABASE",     ATTACH                 },
  { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },
Changes to tool/mksqlite4c.tcl.
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
   sqliteInt.h

   global.c
   env.c
   ctime.c
   status.c
   date.c
   math.c

   os.c
   fault.c
   mem.c
   mem0.c

   mem2.c
   mem3.c
   mem5.c
   mutex.c
   mutex_noop.c
   mutex_unix.c
   mutex_w32.c







<





>







215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
   sqliteInt.h

   global.c
   env.c
   ctime.c
   status.c
   date.c


   os.c
   fault.c
   mem.c
   mem0.c
   mem1.c
   mem2.c
   mem3.c
   mem5.c
   mutex.c
   mutex_noop.c
   mutex_unix.c
   mutex_w32.c
Changes to www/data_encoding.wiki.
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
The data consists of a header area followed by a content area.  The data
begins with a single [./varint.wiki | varint] which is the size of the header area.  The
initial varint itself is not considered part of the header.  The header
is composed of one or two varints for each column in the table.  The varints
determines the datatype and size of the value for that column:

<blockquote><table border=1 cellpadding=5>
<tr><th> Encoding<br>Name <th> Header<br>Code (N)<th> Bytes of <br> Payload
    <th>Description
<tr><td>NULL<td>   0       <td> 0   <td> NULL
<tr><td>ZERO<td>   1       <td> 0   <td> Zero
<tr><td>ONE<td>    2       <td> 0   <td> One
<tr><td>INT<td>    3..10   <td> N-2 <td> Signed integer
<tr><td>NUM<td>    11..21  <td> N-9 <td> Floating-point number
<tr><td>STRING<td> 22+4*K  <td> K   <td> String
<tr><td>BLOB<td>   23+4*K  <td> K   <td> Inline blob
<tr><td>KEY<td>    24+4*K  <td> 0   <td> Content in key at offset K/2.
                                         Floating-point if LSB of K is 1.
<tr><td>TYPED<td>  25+4*K  <td> K   <td> Typed blob, followed by a
                                         single varint type code
</table></blockquote>

Header codes NULL, ZERO, and ONE are self describing and have no content in the 
payload area.

Strings (STRING) can be either UTF8, UTF16le, or UTF16be.  If the first byte of the
payload is 0x00, 0x01, or 0x02 then that byte is ignored and the remaining
bytes are UTF8, UTF16le, or UTF16be respectively.  If the first byte is 0x03
or larger, then the entire string including the first byte is UTF8.  An empty
string consists of the header code 22 and no payload.

Blobs (BLOB) are stored as a sequence of bytes with no encoding.  An empty blob
is header code 23.  A one-byte blob is header code 27.  And so forth.

The KEY header code indicates that the actually content of the column is in the
key portion of the key/value pair at an offset of K/2 bytes from the beginning of
the key.  Numeric values should be interpreted as floating point if K is odd and
as integers if K is even.

A "typed blob" (TYPED) is a sequence of bytes in an application-defined type.
The type is determined by a varint that immediately follows the initial
varint.  Hence, a typed blob uses two varints in the header whereas all
other types use a single varint.

The content of INT is the specified number of bytes for the signed integer.
The most significant bytes are first.

The content of a number (NUM) is two varints.  The first varint has a value
which is abs(e)*4 + (e<0)*2 + (m<0).  The second varint is abs(m).
The maximum e is 999, which gives a max varint value of 3999 or 0xf906af, for
a maximum first varint size of 3.  Values of e greater than 999 (used for
Inf and NaN) are represented as a -0.  The second varint can be a full 9 bytes.
Example values:

<blockquote><table border=0>







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


<
<
<
|


|
<

<
<
<
<
<
<
<
<
|




<
<
<
|







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
The data consists of a header area followed by a content area.  The data
begins with a single [./varint.wiki | varint] which is the size of the header area.  The
initial varint itself is not considered part of the header.  The header
is composed of one or two varints for each column in the table.  The varints
determines the datatype and size of the value for that column:

<blockquote><table border=1 cellpadding=5>


<tr><td>  0       <td>   NULL
<tr><td>  1       <td>   zero
<tr><td>  2       <td>   one
<tr><td>  3..10   <td>   (N-2)-byte signed integer
<tr><td>  11..21  <td>   (N-9)-byte number (two varints: min 2, max 12 bytes)
<tr><td>  22+3*K  <td>   K-byte string
<tr><td>  23+3*K  <td>   K-byte inline blob



<tr><td>  24+3*K  <td>   K-byte typed blob, followed by a single varint type code
</table></blockquote>




Strings can be either UTF8, UTF16le, or UTF16be.  If the first byte of the
payload is 0x00, 0x01, or 0x02 then that byte is ignored and the remaining
bytes are UTF8, UTF16le, or UTF16be respectively.  If the first byte is 0x03
or larger, then the entire string including the first byte is UTF8.










A "typed blob" is a sequence of bytes in an application-defined type.
The type is determined by a varint that immediately follows the initial
varint.  Hence, a typed blob uses two varints in the header whereas all
other types use a single varint.




The content of a number is two varints.  The first varint has a value
which is abs(e)*4 + (e<0)*2 + (m<0).  The second varint is abs(m).
The maximum e is 999, which gives a max varint value of 3999 or 0xf906af, for
a maximum first varint size of 3.  Values of e greater than 999 (used for
Inf and NaN) are represented as a -0.  The second varint can be a full 9 bytes.
Example values:

<blockquote><table border=0>
74
75
76
77
78
79
80

Initially, the followed typed blobs are defined:

<blockquote><table border=0>
<tr><td>   0  <td>    external blob
<tr><td>   1  <td>    big int
<tr><td>   2  <td>    date/time
</table></blockquote>








>
54
55
56
57
58
59
60
61
Initially, the followed typed blobs are defined:

<blockquote><table border=0>
<tr><td>   0  <td>    external blob
<tr><td>   1  <td>    big int
<tr><td>   2  <td>    date/time
</table></blockquote>

Changes to www/key_encoding.wiki.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<title>Key Encoding</title>

This note describes how record keys are encoded.  The encoding is designed
such that memcmp() can be used to sort the keys into their proper order.

A key consists of a table number followed by a list of one or more SQL 
values.  Each SQL value in the list has one of the following types:  NULL, 
numeric, text, or binary.  Keys are compared value by value, from left to 
right, until a difference is found. The first difference determines the
key order.

The table number is a [./varint.wiki | varint]
that identifies the table to which the key
belongs.  Table numbers always sort in ASCENDING order.

Each SQL value has a sort-order which is either ASCENDING or DESCENDING.  The








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<title>Key Encoding</title>

This note describes how record keys are encoded.  The encoding is designed
such that memcmp() can be used to sort the keys into their proper order.

A key consists of a table number followed by a list of one or more SQL 
values.  Each SQL value in the list has one of the following types:  NULL, 
numeric, text, or binary.  Keys are compared value by value, from left to 
right, until a difference if found. The first difference determines the
key order.

The table number is a [./varint.wiki | varint]
that identifies the table to which the key
belongs.  Table numbers always sort in ASCENDING order.

Each SQL value has a sort-order which is either ASCENDING or DESCENDING.  The
Changes to www/porting.wiki.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    /* pError now points to a buffer containing the current error message
    ** encoded using native byte-order UTF-16. Do something with it! */
  }

  /* Free the contents of the buffer (and hence pError) */
  sqlite4_buffer_clear(&buf);
</pre>

<h3> CHECK Constraint Evaluation </h3>

<p>
In SQLite4, CHECK constraints are evaluated after affinities are applied
to new column values. In SQLite3, the CHECK constraints are evaluated before
affinities are applied.










<
<
<
<
<
<
<
<
<

75
76
77
78
79
80
81









82
    /* pError now points to a buffer containing the current error message
    ** encoded using native byte-order UTF-16. Do something with it! */
  }

  /* Free the contents of the buffer (and hence pError) */
  sqlite4_buffer_clear(&buf);
</pre>