System.Data.SQLite

Check-in [dfa2a55bad]
Login

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

Overview
Comment:Update SQLite to the latest trunk code. Add managed virtual table support for the estimatedRows field.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | win32heap
Files: files | file ages | folders
SHA1: dfa2a55bad2d1c8729a3caa66b83bada6d0ac115
User & Date: mistachkin 2013-11-11 20:41:07.272
Context
2013-11-11
20:51
Merge all recent memory management (and other) enhancements to trunk. check-in: 8f8f493cbf user: mistachkin tags: trunk
20:41
Update SQLite to the latest trunk code. Add managed virtual table support for the estimatedRows field. Closed-Leaf check-in: dfa2a55bad user: mistachkin tags: win32heap
02:18
Update SQLite core library to the latest trunk code. Refer to the Win32-specific core library functions only when it is likely they will be available. check-in: 76131c4fc9 user: mistachkin tags: win32heap
Changes
Unified Diff Ignore Whitespace Patch
Changes to SQLite.Interop/src/core/sqlite3.c.
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
#define SQLITE_SOURCE_ID      "2013-11-11 01:42:10 aaed7d1d3ba0aef9f99fb157d3704b9f279aef71"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
#define SQLITE_SOURCE_ID      "2013-11-11 19:56:35 f58d57017199421167dae8ebc67db2f19be45082"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
5319
5320
5321
5322
5323
5324
5325
5326

5327

5328
5329










5330
5331
5332
5333
5334
5335
5336
** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
** ^The estimatedCost value is an estimate of the cost of doing the

** particular lookup.  A full scan of a table with N entries should have

** a cost of N.  A binary search of a table of N entries should have a
** cost of approximately log(N).










*/
struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column on left-hand side of constraint */
     unsigned char op;         /* Constraint operator */







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







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
** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
** ^The estimatedCost value is an estimate of the cost of a particular
** strategy. A cost of N indicates that the cost of the strategy is similar
** to a linear scan of an SQLite table with N rows. A cost of log(N) 
** indicates that the expense of the operation is similar to that of a
** binary search on a unique indexed field of an SQLite table with N rows.
**
** ^The estimatedRows value is an estimate of the number of rows that
** will be returned by the strategy.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite version 3.8.2. If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting 
** to read or write the estimatedRows field are undefined (but are likely 
** to included crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column on left-hand side of constraint */
     unsigned char op;         /* Constraint operator */
5347
5348
5349
5350
5351
5352
5353
5354

5355
5356
5357
5358
5359
5360
5361
    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;      /* Estimated cost of using this index */

};

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents







|
>







5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;           /* Estimated cost of using this index */
  sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
};

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents
35292
35293
35294
35295
35296
35297
35298
35299
35300
35301
35302
35303
35304
35305
35306
  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
  const char *zName,        /* Name of the file (UTF-8) */
  sqlite3_file *id,         /* Write the SQLite file handle here */
  int flags,                /* Open mode flags */
  int *pOutFlags            /* Status return flags */
){
  HANDLE h;
  DWORD lastErrno;
  DWORD dwDesiredAccess;
  DWORD dwShareMode;
  DWORD dwCreationDisposition;
  DWORD dwFlagsAndAttributes = 0;
#if SQLITE_OS_WINCE
  int isTemp = 0;
#endif







|







35305
35306
35307
35308
35309
35310
35311
35312
35313
35314
35315
35316
35317
35318
35319
  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
  const char *zName,        /* Name of the file (UTF-8) */
  sqlite3_file *id,         /* Write the SQLite file handle here */
  int flags,                /* Open mode flags */
  int *pOutFlags            /* Status return flags */
){
  HANDLE h;
  DWORD lastErrno = 0;
  DWORD dwDesiredAccess;
  DWORD dwShareMode;
  DWORD dwCreationDisposition;
  DWORD dwFlagsAndAttributes = 0;
#if SQLITE_OS_WINCE
  int isTemp = 0;
#endif
35583
35584
35585
35586
35587
35588
35589
35590
35591
35592
35593
35594
35595
35596
35597
  sqlite3_vfs *pVfs,          /* Not used on win32 */
  const char *zFilename,      /* Name of file to delete */
  int syncDir                 /* Not used on win32 */
){
  int cnt = 0;
  int rc;
  DWORD attr;
  DWORD lastErrno;
  void *zConverted;
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(syncDir);

  SimulateIOError(return SQLITE_IOERR_DELETE);
  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));








|







35596
35597
35598
35599
35600
35601
35602
35603
35604
35605
35606
35607
35608
35609
35610
  sqlite3_vfs *pVfs,          /* Not used on win32 */
  const char *zFilename,      /* Name of file to delete */
  int syncDir                 /* Not used on win32 */
){
  int cnt = 0;
  int rc;
  DWORD attr;
  DWORD lastErrno = 0;
  void *zConverted;
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(syncDir);

  SimulateIOError(return SQLITE_IOERR_DELETE);
  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));

35691
35692
35693
35694
35695
35696
35697
35698
35699
35700
35701
35702
35703
35704
35705
  sqlite3_vfs *pVfs,         /* Not used on win32 */
  const char *zFilename,     /* Name of file to check */
  int flags,                 /* Type of test to make on this file */
  int *pResOut               /* OUT: Result */
){
  DWORD attr;
  int rc = 0;
  DWORD lastErrno;
  void *zConverted;
  UNUSED_PARAMETER(pVfs);

  SimulateIOError( return SQLITE_IOERR_ACCESS; );
  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
           zFilename, flags, pResOut));








|







35704
35705
35706
35707
35708
35709
35710
35711
35712
35713
35714
35715
35716
35717
35718
  sqlite3_vfs *pVfs,         /* Not used on win32 */
  const char *zFilename,     /* Name of file to check */
  int flags,                 /* Type of test to make on this file */
  int *pResOut               /* OUT: Result */
){
  DWORD attr;
  int rc = 0;
  DWORD lastErrno = 0;
  void *zConverted;
  UNUSED_PARAMETER(pVfs);

  SimulateIOError( return SQLITE_IOERR_ACCESS; );
  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
           zFilename, flags, pResOut));

61440
61441
61442
61443
61444
61445
61446

61447
61448
61449
61450
61451
61452
61453
61454
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){
      int p2 = pIn->p2;
      VdbeOp *pOut = &p->aOp[i+addr];
      pOut->opcode = pIn->opcode;
      pOut->p1 = pIn->p1;

      if( p2<0 && (sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP)!=0 ){
        pOut->p2 = addr + ADDR(p2);
      }else{
        pOut->p2 = p2;
      }
      pOut->p3 = pIn->p3;
      pOut->p4type = P4_NOTUSED;
      pOut->p4.p = 0;







>
|







61453
61454
61455
61456
61457
61458
61459
61460
61461
61462
61463
61464
61465
61466
61467
61468
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){
      int p2 = pIn->p2;
      VdbeOp *pOut = &p->aOp[i+addr];
      pOut->opcode = pIn->opcode;
      pOut->p1 = pIn->p1;
      if( p2<0 ){
        assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
        pOut->p2 = addr + ADDR(p2);
      }else{
        pOut->p2 = p2;
      }
      pOut->p3 = pIn->p3;
      pOut->p4type = P4_NOTUSED;
      pOut->p4.p = 0;
67324
67325
67326
67327
67328
67329
67330

67331
67332
67333
67334
67335
67336
67337
67338
67339
67340
67341
67342
67343
67344
67345
67346
67347
      testcase( pOp->p5==2 );
      testcase( pOp->p5==3 );
      testcase( pOp->p5==4 );
      u.ab.zType = azType[pOp->p5-1];
    }else{
      u.ab.zType = 0;
    }

    u.ab.zLogFmt = "abort at %d in [%s]: %s";
    if( u.ab.zType && pOp->p4.z ){
      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
                       u.ab.zType, pOp->p4.z);
    }else if( pOp->p4.z ){
      sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
    }else if( u.ab.zType ){
      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType);
    }else{
      u.ab.zLogFmt = "abort at %d in [%s]";
    }
    sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
  if( rc==SQLITE_BUSY ){
    p->rc = rc = SQLITE_BUSY;







>






|

<
<







67338
67339
67340
67341
67342
67343
67344
67345
67346
67347
67348
67349
67350
67351
67352
67353


67354
67355
67356
67357
67358
67359
67360
      testcase( pOp->p5==2 );
      testcase( pOp->p5==3 );
      testcase( pOp->p5==4 );
      u.ab.zType = azType[pOp->p5-1];
    }else{
      u.ab.zType = 0;
    }
    assert( u.ab.zType!=0 || pOp->p4.z!=0 );
    u.ab.zLogFmt = "abort at %d in [%s]: %s";
    if( u.ab.zType && pOp->p4.z ){
      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
                       u.ab.zType, pOp->p4.z);
    }else if( pOp->p4.z ){
      sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
    }else{
      sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType);


    }
    sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
  if( rc==SQLITE_BUSY ){
    p->rc = rc = SQLITE_BUSY;
68773
68774
68775
68776
68777
68778
68779

68780
68781
68782
68783
68784
68785
68786
68787
68788
68789
68790
68791
68792
68793
68794
68795
68796
68797
68798
68799
68800
68801
68802
      assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 );
      u.ap.payloadSize = (u32)u.ap.payloadSize64;
    }else{
      assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.payloadSize);
      assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
    }

  }else if( ALWAYS(u.ap.pC->pseudoTableReg>0) ){
    u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg];
    if( u.ap.pC->multiPseudo ){
      sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem);
      Deephemeralize(u.ap.pDest);
      goto op_column_out;
    }
    assert( u.ap.pReg->flags & MEM_Blob );
    assert( memIsValid(u.ap.pReg) );
    u.ap.payloadSize = u.ap.pReg->n;
    u.ap.zRec = u.ap.pReg->z;
    u.ap.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
    assert( u.ap.payloadSize==0 || u.ap.zRec!=0 );
  }else{
    /* Consider the row to be NULL */
    u.ap.payloadSize = 0;
  }

  /* If u.ap.payloadSize is 0, then just store a NULL.  This can happen because of
  ** nullRow or because of a corrupt database. */
  if( u.ap.payloadSize==0 ){
    MemSetTypeFlag(u.ap.pDest, MEM_Null);
    goto op_column_out;







>
|












<
<
<







68786
68787
68788
68789
68790
68791
68792
68793
68794
68795
68796
68797
68798
68799
68800
68801
68802
68803
68804
68805
68806



68807
68808
68809
68810
68811
68812
68813
      assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 );
      u.ap.payloadSize = (u32)u.ap.payloadSize64;
    }else{
      assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.payloadSize);
      assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
    }
  }else{
    assert( u.ap.pC->pseudoTableReg>0 );
    u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg];
    if( u.ap.pC->multiPseudo ){
      sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem);
      Deephemeralize(u.ap.pDest);
      goto op_column_out;
    }
    assert( u.ap.pReg->flags & MEM_Blob );
    assert( memIsValid(u.ap.pReg) );
    u.ap.payloadSize = u.ap.pReg->n;
    u.ap.zRec = u.ap.pReg->z;
    u.ap.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
    assert( u.ap.payloadSize==0 || u.ap.zRec!=0 );



  }

  /* If u.ap.payloadSize is 0, then just store a NULL.  This can happen because of
  ** nullRow or because of a corrupt database. */
  if( u.ap.payloadSize==0 ){
    MemSetTypeFlag(u.ap.pDest, MEM_Null);
    goto op_column_out;
69186
69187
69188
69189
69190
69191
69192
69193
69194
69195
69196
69197
69198
69199
69200
69201
69202
69203
69204
case OP_Count: {         /* out2-prerelease */
#if 0  /* local variables moved into u.as */
  i64 nEntry;
  BtCursor *pCrsr;
#endif /* local variables moved into u.as */

  u.as.pCrsr = p->apCsr[pOp->p1]->pCursor;
  if( ALWAYS(u.as.pCrsr) ){
    rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry);
  }else{
    u.as.nEntry = 0;
  }
  pOut->u.i = u.as.nEntry;
  break;
}
#endif

/* Opcode: Savepoint P1 * * P4 *
**







|
|
<
<
<







69197
69198
69199
69200
69201
69202
69203
69204
69205



69206
69207
69208
69209
69210
69211
69212
case OP_Count: {         /* out2-prerelease */
#if 0  /* local variables moved into u.as */
  i64 nEntry;
  BtCursor *pCrsr;
#endif /* local variables moved into u.as */

  u.as.pCrsr = p->apCsr[pOp->p1]->pCursor;
  assert( u.as.pCrsr );
  rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry);



  pOut->u.i = u.as.nEntry;
  break;
}
#endif

/* Opcode: Savepoint P1 * * P4 *
**
70023
70024
70025
70026
70027
70028
70029
70030
70031
70032
70033
70034
70035
70036
70037
70038
70039
70040
70041
70042
70043
70044
70045
70046
70047
70048
70049
70050
70051
70052
70053
70054
70055
70056
70057
70058
70059
70060
70061
70062
70063
70064
70065
70066
70067
70068
70069
70070
70071
70072
70073
70074
70075
70076
70077
70078
70079
70080
70081
70082
70083
70084
70085
70086
70087
70088
70089
70090
70091
70092
70093
70094
70095
70096
70097
70098
70099
70100
70101
70102
70103
70104
70105
70106
70107
70108
70109
70110
70111
70112
70113
70114
70115
70116
70117
70118
70119
70120
70121
70122
70123
70124
70125
70126
70127
70128
70129
70130
70131
70132
70133
70134
70135
70136
70137
70138
70139
70140
70141
70142
70143
70144
70145
70146
70147
70148
70149
70150
70151
70152
70153
70154
70155
70156
70157
70158
70159
70160
70161
70162
70163
  u.bd.pC = p->apCsr[pOp->p1];
  assert( u.bd.pC!=0 );
  assert( u.bd.pC->pseudoTableReg==0 );
  assert( OP_SeekLe == OP_SeekLt+1 );
  assert( OP_SeekGe == OP_SeekLt+2 );
  assert( OP_SeekGt == OP_SeekLt+3 );
  assert( u.bd.pC->isOrdered );
  if( ALWAYS(u.bd.pC->pCursor!=0) ){
    u.bd.oc = pOp->opcode;
    u.bd.pC->nullRow = 0;
    if( u.bd.pC->isTable ){
      /* The input value in P3 might be of any type: integer, real, string,
      ** blob, or NULL.  But it needs to be an integer before we can do
      ** the seek, so covert it. */
      pIn3 = &aMem[pOp->p3];
      applyNumericAffinity(pIn3);
      u.bd.iKey = sqlite3VdbeIntValue(pIn3);
      u.bd.pC->rowidIsValid = 0;

      /* If the P3 value could not be converted into an integer without
      ** loss of information, then special processing is required... */
      if( (pIn3->flags & MEM_Int)==0 ){
        if( (pIn3->flags & MEM_Real)==0 ){
          /* If the P3 value cannot be converted into any kind of a number,
          ** then the seek is not possible, so jump to P2 */
          pc = pOp->p2 - 1;
          break;
        }
        /* If we reach this point, then the P3 value must be a floating
        ** point number. */
        assert( (pIn3->flags & MEM_Real)!=0 );

        if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){
          /* The P3 value is too large in magnitude to be expressed as an
          ** integer. */
          u.bd.res = 1;
          if( pIn3->r<0 ){
            if( u.bd.oc>=OP_SeekGe ){  assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
              rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res);
              if( rc!=SQLITE_OK ) goto abort_due_to_error;
            }
          }else{
            if( u.bd.oc<=OP_SeekLe ){  assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
              rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res);
              if( rc!=SQLITE_OK ) goto abort_due_to_error;
            }
          }
          if( u.bd.res ){
            pc = pOp->p2 - 1;
          }
          break;
        }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){
          /* Use the ceiling() function to convert real->int */
          if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++;
        }else{
          /* Use the floor() function to convert real->int */
          assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt );
          if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--;
        }
      }
      rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      if( u.bd.res==0 ){
        u.bd.pC->rowidIsValid = 1;
        u.bd.pC->lastRowid = u.bd.iKey;
      }
    }else{
      u.bd.nField = pOp->p4.i;
      assert( pOp->p4type==P4_INT32 );
      assert( u.bd.nField>0 );
      u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
      u.bd.r.nField = (u16)u.bd.nField;

      /* The next line of code computes as follows, only faster:
      **   if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){
      **     u.bd.r.flags = UNPACKED_INCRKEY;
      **   }else{
      **     u.bd.r.flags = 0;
      **   }
      */
      u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt)));
      assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY );
      assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY );
      assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 );
      assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 );

      u.bd.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
      { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); }
#endif
      ExpandBlob(u.bd.r.aMem);
      rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, &u.bd.r, 0, 0, &u.bd.res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      u.bd.pC->rowidIsValid = 0;
    }
    u.bd.pC->deferredMoveto = 0;
    u.bd.pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
    if( u.bd.oc>=OP_SeekGe ){  assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
      if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){
        rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        u.bd.pC->rowidIsValid = 0;
      }else{
        u.bd.res = 0;
      }
    }else{
      assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
      if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){
        rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        u.bd.pC->rowidIsValid = 0;
      }else{
        /* u.bd.res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor);
      }
    }
    assert( pOp->p2>0 );
    if( u.bd.res ){
      pc = pOp->p2 - 1;
    }
  }else{
    /* This happens when attempting to open the sqlite3_master table
    ** for read access returns SQLITE_EMPTY. In this case always
    ** take the jump (since there are no records in the table).
    */
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
** Synopsis:  intkey=r[P2]







|
|
|
|
|
|
|
|
|
|
|

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

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

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

|

|

|
|
|
|
|
|
|
|
|

|

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







70031
70032
70033
70034
70035
70036
70037
70038
70039
70040
70041
70042
70043
70044
70045
70046
70047
70048
70049
70050
70051
70052
70053
70054
70055
70056
70057
70058
70059
70060
70061
70062
70063
70064
70065
70066
70067
70068
70069
70070
70071
70072
70073
70074
70075
70076
70077
70078
70079
70080
70081
70082
70083
70084
70085
70086
70087
70088
70089
70090
70091
70092
70093
70094
70095
70096
70097
70098
70099
70100
70101
70102
70103
70104
70105
70106
70107
70108
70109
70110
70111
70112
70113
70114
70115
70116
70117
70118
70119
70120
70121
70122
70123
70124
70125
70126
70127
70128
70129
70130
70131
70132
70133
70134
70135
70136
70137
70138
70139
70140
70141
70142
70143
70144
70145
70146
70147
70148
70149
70150
70151
70152
70153
70154
70155
70156
70157







70158
70159
70160
70161
70162
70163
70164
  u.bd.pC = p->apCsr[pOp->p1];
  assert( u.bd.pC!=0 );
  assert( u.bd.pC->pseudoTableReg==0 );
  assert( OP_SeekLe == OP_SeekLt+1 );
  assert( OP_SeekGe == OP_SeekLt+2 );
  assert( OP_SeekGt == OP_SeekLt+3 );
  assert( u.bd.pC->isOrdered );
  assert( u.bd.pC->pCursor!=0 );
  u.bd.oc = pOp->opcode;
  u.bd.pC->nullRow = 0;
  if( u.bd.pC->isTable ){
    /* The input value in P3 might be of any type: integer, real, string,
    ** blob, or NULL.  But it needs to be an integer before we can do
    ** the seek, so covert it. */
    pIn3 = &aMem[pOp->p3];
    applyNumericAffinity(pIn3);
    u.bd.iKey = sqlite3VdbeIntValue(pIn3);
    u.bd.pC->rowidIsValid = 0;

    /* If the P3 value could not be converted into an integer without
    ** loss of information, then special processing is required... */
    if( (pIn3->flags & MEM_Int)==0 ){
      if( (pIn3->flags & MEM_Real)==0 ){
        /* If the P3 value cannot be converted into any kind of a number,
        ** then the seek is not possible, so jump to P2 */
        pc = pOp->p2 - 1;
        break;
      }
      /* If we reach this point, then the P3 value must be a floating
      ** point number. */
      assert( (pIn3->flags & MEM_Real)!=0 );

      if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){
        /* The P3 value is too large in magnitude to be expressed as an
        ** integer. */
        u.bd.res = 1;
        if( pIn3->r<0 ){
          if( u.bd.oc>=OP_SeekGe ){  assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
            rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;
          }
        }else{
          if( u.bd.oc<=OP_SeekLe ){  assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
            rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;
          }
        }
        if( u.bd.res ){
          pc = pOp->p2 - 1;
        }
        break;
      }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){
        /* Use the ceiling() function to convert real->int */
        if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++;
      }else{
        /* Use the floor() function to convert real->int */
        assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt );
        if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--;
      }
    }
    rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    if( u.bd.res==0 ){
      u.bd.pC->rowidIsValid = 1;
      u.bd.pC->lastRowid = u.bd.iKey;
    }
  }else{
    u.bd.nField = pOp->p4.i;
    assert( pOp->p4type==P4_INT32 );
    assert( u.bd.nField>0 );
    u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
    u.bd.r.nField = (u16)u.bd.nField;

    /* The next line of code computes as follows, only faster:
    **   if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){
    **     u.bd.r.flags = UNPACKED_INCRKEY;
    **   }else{
    **     u.bd.r.flags = 0;
    **   }
    */
    u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt)));
    assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY );
    assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY );
    assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 );
    assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 );

    u.bd.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
    { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); }
#endif
    ExpandBlob(u.bd.r.aMem);
    rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, &u.bd.r, 0, 0, &u.bd.res);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    u.bd.pC->rowidIsValid = 0;
  }
  u.bd.pC->deferredMoveto = 0;
  u.bd.pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
  sqlite3_search_count++;
#endif
  if( u.bd.oc>=OP_SeekGe ){  assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
    if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){
      rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      u.bd.pC->rowidIsValid = 0;
    }else{
      u.bd.res = 0;
    }
  }else{
    assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
    if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){
      rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      u.bd.pC->rowidIsValid = 0;
    }else{
      /* u.bd.res might be negative because the table is empty.  Check to
      ** see if this is the case.
      */
      u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor);
    }
  }
  assert( pOp->p2>0 );
  if( u.bd.res ){







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

/* Opcode: Seek P1 P2 * * *
** Synopsis:  intkey=r[P2]
70173
70174
70175
70176
70177
70178
70179
70180
70181
70182
70183
70184
70185
70186
70187
70188
70189
70190
70191
70192
70193
70194
#if 0  /* local variables moved into u.be */
  VdbeCursor *pC;
#endif /* local variables moved into u.be */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.be.pC = p->apCsr[pOp->p1];
  assert( u.be.pC!=0 );
  if( ALWAYS(u.be.pC->pCursor!=0) ){
    assert( u.be.pC->isTable );
    u.be.pC->nullRow = 0;
    pIn2 = &aMem[pOp->p2];
    u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
    u.be.pC->rowidIsValid = 0;
    u.be.pC->deferredMoveto = 1;
  }
  break;
}
  

/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**







|
|
|
|
|
|
|
<







70174
70175
70176
70177
70178
70179
70180
70181
70182
70183
70184
70185
70186
70187

70188
70189
70190
70191
70192
70193
70194
#if 0  /* local variables moved into u.be */
  VdbeCursor *pC;
#endif /* local variables moved into u.be */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.be.pC = p->apCsr[pOp->p1];
  assert( u.be.pC!=0 );
  assert( u.be.pC->pCursor!=0 );
  assert( u.be.pC->isTable );
  u.be.pC->nullRow = 0;
  pIn2 = &aMem[pOp->p2];
  u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
  u.be.pC->rowidIsValid = 0;
  u.be.pC->deferredMoveto = 1;

  break;
}
  

/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
70256
70257
70258
70259
70260
70261
70262
70263
70264
70265
70266
70267
70268
70269
70270
70271
70272
70273
70274
70275
70276
70277
70278
70279
70280
70281
70282
70283
70284
70285
70286
70287
70288
70289
70290
70291
70292
70293
70294
70295
70296
70297
70298
70299
70300
70301
70302
70303
70304
70305
70306
70307
70308
70309
70310
70311
70312
70313
70314
70315
70316
70317
70318
70319
70320
70321

  u.bf.alreadyExists = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p4type==P4_INT32 );
  u.bf.pC = p->apCsr[pOp->p1];
  assert( u.bf.pC!=0 );
  pIn3 = &aMem[pOp->p3];
  if( ALWAYS(u.bf.pC->pCursor!=0) ){

    assert( u.bf.pC->isTable==0 );
    if( pOp->p4.i>0 ){
      u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo;
      u.bf.r.nField = (u16)pOp->p4.i;
      u.bf.r.aMem = pIn3;
#ifdef SQLITE_DEBUG
      {
        int i;
        for(i=0; i<u.bf.r.nField; i++){
          assert( memIsValid(&u.bf.r.aMem[i]) );
          if( i ) REGISTER_TRACE(pOp->p3+i, &u.bf.r.aMem[i]);
        }
      }
#endif
      u.bf.r.flags = UNPACKED_PREFIX_MATCH;
      u.bf.pIdxKey = &u.bf.r;
    }else{
      u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
          u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree
      );
      if( u.bf.pIdxKey==0 ) goto no_mem;
      assert( pIn3->flags & MEM_Blob );
      assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
      sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey);
      u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
    }
    if( pOp->opcode==OP_NoConflict ){
      /* For the OP_NoConflict opcode, take the jump if any of the
      ** input fields are NULL, since any key with a NULL will not
      ** conflict */
      for(u.bf.ii=0; u.bf.ii<u.bf.r.nField; u.bf.ii++){
        if( u.bf.r.aMem[u.bf.ii].flags & MEM_Null ){
          pc = pOp->p2 - 1;
          break;
        }
      }
    }
    rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res);
    if( pOp->p4.i==0 ){
      sqlite3DbFree(db, u.bf.pFree);
    }
    if( rc!=SQLITE_OK ){
      break;
    }
    u.bf.pC->seekResult = u.bf.res;
    u.bf.alreadyExists = (u.bf.res==0);
    u.bf.pC->nullRow = 1-u.bf.alreadyExists;
    u.bf.pC->deferredMoveto = 0;
    u.bf.pC->cacheStatus = CACHE_STALE;
  }
  if( pOp->opcode==OP_Found ){
    if( u.bf.alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !u.bf.alreadyExists ) pc = pOp->p2 - 1;
  }
  break;
}







|
<
|
|
|
|
|

|
|
|
|
|
|
|

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







70256
70257
70258
70259
70260
70261
70262
70263

70264
70265
70266
70267
70268
70269
70270
70271
70272
70273
70274
70275
70276
70277
70278
70279
70280
70281
70282
70283
70284
70285
70286
70287
70288
70289
70290
70291
70292
70293
70294
70295
70296
70297
70298
70299
70300
70301
70302
70303
70304
70305
70306
70307
70308
70309
70310
70311
70312

70313
70314
70315
70316
70317
70318
70319

  u.bf.alreadyExists = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p4type==P4_INT32 );
  u.bf.pC = p->apCsr[pOp->p1];
  assert( u.bf.pC!=0 );
  pIn3 = &aMem[pOp->p3];
  assert( u.bf.pC->pCursor!=0 );

  assert( u.bf.pC->isTable==0 );
  if( pOp->p4.i>0 ){
    u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo;
    u.bf.r.nField = (u16)pOp->p4.i;
    u.bf.r.aMem = pIn3;
#ifdef SQLITE_DEBUG
    {
      int i;
      for(i=0; i<u.bf.r.nField; i++){
        assert( memIsValid(&u.bf.r.aMem[i]) );
        if( i ) REGISTER_TRACE(pOp->p3+i, &u.bf.r.aMem[i]);
      }
    }
#endif
    u.bf.r.flags = UNPACKED_PREFIX_MATCH;
    u.bf.pIdxKey = &u.bf.r;
  }else{
    u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
        u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree
    );
    if( u.bf.pIdxKey==0 ) goto no_mem;
    assert( pIn3->flags & MEM_Blob );
    assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
    sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey);
    u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
  }
  if( pOp->opcode==OP_NoConflict ){
    /* For the OP_NoConflict opcode, take the jump if any of the
    ** input fields are NULL, since any key with a NULL will not
    ** conflict */
    for(u.bf.ii=0; u.bf.ii<u.bf.r.nField; u.bf.ii++){
      if( u.bf.r.aMem[u.bf.ii].flags & MEM_Null ){
        pc = pOp->p2 - 1;
        break;
      }
    }
  }
  rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res);
  if( pOp->p4.i==0 ){
    sqlite3DbFree(db, u.bf.pFree);
  }
  if( rc!=SQLITE_OK ){
    break;
  }
  u.bf.pC->seekResult = u.bf.res;
  u.bf.alreadyExists = (u.bf.res==0);
  u.bf.pC->nullRow = 1-u.bf.alreadyExists;
  u.bf.pC->deferredMoveto = 0;
  u.bf.pC->cacheStatus = CACHE_STALE;

  if( pOp->opcode==OP_Found ){
    if( u.bf.alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !u.bf.alreadyExists ) pc = pOp->p2 - 1;
  }
  break;
}
70346
70347
70348
70349
70350
70351
70352
70353
70354
70355
70356
70357
70358
70359
70360
70361
70362
70363
70364
70365
70366
70367
70368
70369
70370
70371
70372
70373
70374
70375
70376
70377
70378
70379
70380
70381
  assert( pIn3->flags & MEM_Int );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bg.pC = p->apCsr[pOp->p1];
  assert( u.bg.pC!=0 );
  assert( u.bg.pC->isTable );
  assert( u.bg.pC->pseudoTableReg==0 );
  u.bg.pCrsr = u.bg.pC->pCursor;
  if( ALWAYS(u.bg.pCrsr!=0) ){
    u.bg.res = 0;
    u.bg.iKey = pIn3->u.i;
    rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
    u.bg.pC->lastRowid = pIn3->u.i;
    u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
    u.bg.pC->nullRow = 0;
    u.bg.pC->cacheStatus = CACHE_STALE;
    u.bg.pC->deferredMoveto = 0;
    if( u.bg.res!=0 ){
      pc = pOp->p2 - 1;
      assert( u.bg.pC->rowidIsValid==0 );
    }
    u.bg.pC->seekResult = u.bg.res;
  }else{
    /* This happens when an attempt to open a read cursor on the
    ** sqlite_master table returns SQLITE_EMPTY.
    */
    pc = pOp->p2 - 1;
    assert( u.bg.pC->rowidIsValid==0 );
    u.bg.pC->seekResult = 0;
  }
  break;
}

/* Opcode: Sequence P1 P2 * * *
** Synopsis: r[P2]=rowid
**
** Find the next available sequence number for cursor P1.







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







70344
70345
70346
70347
70348
70349
70350
70351
70352
70353
70354
70355
70356
70357
70358
70359
70360
70361
70362
70363
70364








70365
70366
70367
70368
70369
70370
70371
  assert( pIn3->flags & MEM_Int );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bg.pC = p->apCsr[pOp->p1];
  assert( u.bg.pC!=0 );
  assert( u.bg.pC->isTable );
  assert( u.bg.pC->pseudoTableReg==0 );
  u.bg.pCrsr = u.bg.pC->pCursor;
  assert( u.bg.pCrsr!=0 );
  u.bg.res = 0;
  u.bg.iKey = pIn3->u.i;
  rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
  u.bg.pC->lastRowid = pIn3->u.i;
  u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
  u.bg.pC->nullRow = 0;
  u.bg.pC->cacheStatus = CACHE_STALE;
  u.bg.pC->deferredMoveto = 0;
  if( u.bg.res!=0 ){
    pc = pOp->p2 - 1;
    assert( u.bg.pC->rowidIsValid==0 );
  }
  u.bg.pC->seekResult = u.bg.res;








  break;
}

/* Opcode: Sequence P1 P2 * * *
** Synopsis: r[P2]=rowid
**
** Find the next available sequence number for cursor P1.
70965
70966
70967
70968
70969
70970
70971
70972
70973
70974
70975
70976
70977
70978
70979
70980
70981
#endif /* local variables moved into u.bp */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bp.pC = p->apCsr[pOp->p1];
  assert( u.bp.pC!=0 );
  u.bp.pCrsr = u.bp.pC->pCursor;
  u.bp.res = 0;
  if( ALWAYS(u.bp.pCrsr!=0) ){
    rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
  }
  u.bp.pC->nullRow = (u8)u.bp.res;
  u.bp.pC->deferredMoveto = 0;
  u.bp.pC->rowidIsValid = 0;
  u.bp.pC->cacheStatus = CACHE_STALE;
  if( pOp->p2>0 && u.bp.res ){
    pc = pOp->p2 - 1;
  }







|
|
<







70955
70956
70957
70958
70959
70960
70961
70962
70963

70964
70965
70966
70967
70968
70969
70970
#endif /* local variables moved into u.bp */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bp.pC = p->apCsr[pOp->p1];
  assert( u.bp.pC!=0 );
  u.bp.pCrsr = u.bp.pC->pCursor;
  u.bp.res = 0;
  assert( u.bp.pCrsr!=0 );
  rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);

  u.bp.pC->nullRow = (u8)u.bp.res;
  u.bp.pC->deferredMoveto = 0;
  u.bp.pC->rowidIsValid = 0;
  u.bp.pC->cacheStatus = CACHE_STALE;
  if( pOp->p2>0 && u.bp.res ){
    pc = pOp->p2 - 1;
  }
71140
71141
71142
71143
71144
71145
71146
71147
71148
71149
71150
71151
71152
71153
71154
71155
71156
71157
71158
71159
71160
71161
71162
71163
71164
71165
71166
71167
71168
71169
71170
71171
71172
71173
71174
71175
71176
71177
71178
71179
71180
71181
71182
71183
71184
71185
71186
71187
71188
71189

71190
71191
71192
71193
71194
71195
71196
71197
71198
71199
71200
71201
71202
71203
71204
71205
71206
71207
71208
71209
71210
  u.bs.pC = p->apCsr[pOp->p1];
  assert( u.bs.pC!=0 );
  assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  u.bs.pCrsr = u.bs.pC->pCursor;
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( ALWAYS(u.bs.pCrsr!=0) ){
    assert( u.bs.pC->isTable==0 );
    rc = ExpandBlob(pIn2);
    if( rc==SQLITE_OK ){
      if( isSorter(u.bs.pC) ){
        rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
      }else{
        u.bs.nKey = pIn2->n;
        u.bs.zKey = pIn2->z;
        rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
            ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
            );
        assert( u.bs.pC->deferredMoveto==0 );
        u.bs.pC->cacheStatus = CACHE_STALE;
      }
    }
  }
  break;
}

/* Opcode: IdxDelete P1 P2 P3 * P5
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the 
** index opened by cursor P1.
*/
case OP_IdxDelete: {
#if 0  /* local variables moved into u.bt */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;
#endif /* local variables moved into u.bt */

  assert( pOp->p3>0 );
  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bt.pC = p->apCsr[pOp->p1];
  assert( u.bt.pC!=0 );
  u.bt.pCrsr = u.bt.pC->pCursor;
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( ALWAYS(u.bt.pCrsr!=0) ){

    u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
    u.bt.r.nField = (u16)pOp->p3;
    u.bt.r.flags = UNPACKED_PREFIX_MATCH;
    u.bt.r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
    { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
#endif
    rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
    if( rc==SQLITE_OK && u.bt.res==0 ){
      rc = sqlite3BtreeDelete(u.bt.pCrsr);
    }
    assert( u.bt.pC->deferredMoveto==0 );
    u.bt.pC->cacheStatus = CACHE_STALE;
  }
  break;
}

/* Opcode: IdxRowid P1 P2 * * *
** Synopsis: r[P2]=rowid
**
** Write into register P2 an integer which is the last entry in the record at







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





|




















<
|
>
|
|
|
|

|

|
|
|
|
|
|
<







71129
71130
71131
71132
71133
71134
71135
71136
71137
71138
71139
71140
71141
71142
71143
71144
71145
71146
71147
71148
71149

71150
71151
71152
71153
71154
71155
71156
71157
71158
71159
71160
71161
71162
71163
71164
71165
71166
71167
71168
71169
71170
71171
71172
71173
71174
71175

71176
71177
71178
71179
71180
71181
71182
71183
71184
71185
71186
71187
71188
71189
71190

71191
71192
71193
71194
71195
71196
71197
  u.bs.pC = p->apCsr[pOp->p1];
  assert( u.bs.pC!=0 );
  assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  u.bs.pCrsr = u.bs.pC->pCursor;
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  assert( u.bs.pCrsr!=0 );
  assert( u.bs.pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  if( rc==SQLITE_OK ){
    if( isSorter(u.bs.pC) ){
      rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
    }else{
      u.bs.nKey = pIn2->n;
      u.bs.zKey = pIn2->z;
      rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
          ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
          );
      assert( u.bs.pC->deferredMoveto==0 );
      u.bs.pC->cacheStatus = CACHE_STALE;

    }
  }
  break;
}

/* Opcode: IdxDelete P1 P2 P3 * *
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the 
** index opened by cursor P1.
*/
case OP_IdxDelete: {
#if 0  /* local variables moved into u.bt */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;
#endif /* local variables moved into u.bt */

  assert( pOp->p3>0 );
  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bt.pC = p->apCsr[pOp->p1];
  assert( u.bt.pC!=0 );
  u.bt.pCrsr = u.bt.pC->pCursor;

  assert( u.bt.pCrsr!=0 );
  assert( pOp->p5==0 );
  u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
  u.bt.r.nField = (u16)pOp->p3;
  u.bt.r.flags = UNPACKED_PREFIX_MATCH;
  u.bt.r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
  { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
#endif
  rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
  if( rc==SQLITE_OK && u.bt.res==0 ){
    rc = sqlite3BtreeDelete(u.bt.pCrsr);
  }
  assert( u.bt.pC->deferredMoveto==0 );
  u.bt.pC->cacheStatus = CACHE_STALE;

  break;
}

/* Opcode: IdxRowid P1 P2 * * *
** Synopsis: r[P2]=rowid
**
** Write into register P2 an integer which is the last entry in the record at
71220
71221
71222
71223
71224
71225
71226

71227
71228
71229
71230
71231
71232
71233
71234
71235
71236
71237
71238
71239
71240
71241
71242
71243
71244
71245
71246
71247
  i64 rowid;
#endif /* local variables moved into u.bu */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bu.pC = p->apCsr[pOp->p1];
  assert( u.bu.pC!=0 );
  u.bu.pCrsr = u.bu.pC->pCursor;

  pOut->flags = MEM_Null;
  if( ALWAYS(u.bu.pCrsr!=0) ){
    rc = sqlite3VdbeCursorMoveto(u.bu.pC);
    if( NEVER(rc) ) goto abort_due_to_error;
    assert( u.bu.pC->deferredMoveto==0 );
    assert( u.bu.pC->isTable==0 );
    if( !u.bu.pC->nullRow ){
      rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pOut->u.i = u.bu.rowid;
      pOut->flags = MEM_Int;
    }
  }
  break;
}

/* Opcode: IdxGE P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**







>

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







71207
71208
71209
71210
71211
71212
71213
71214
71215

71216
71217
71218
71219
71220
71221
71222
71223
71224
71225
71226

71227
71228
71229
71230
71231
71232
71233
  i64 rowid;
#endif /* local variables moved into u.bu */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bu.pC = p->apCsr[pOp->p1];
  assert( u.bu.pC!=0 );
  u.bu.pCrsr = u.bu.pC->pCursor;
  assert( u.bu.pCrsr!=0 );
  pOut->flags = MEM_Null;

  rc = sqlite3VdbeCursorMoveto(u.bu.pC);
  if( NEVER(rc) ) goto abort_due_to_error;
  assert( u.bu.pC->deferredMoveto==0 );
  assert( u.bu.pC->isTable==0 );
  if( !u.bu.pC->nullRow ){
    rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    pOut->u.i = u.bu.rowid;
    pOut->flags = MEM_Int;

  }
  break;
}

/* Opcode: IdxGE P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
71278
71279
71280
71281
71282
71283
71284
71285
71286
71287
71288
71289
71290
71291
71292
71293
71294
71295
71296
71297
71298
71299
71300
71301
71302
71303
71304
71305
71306
71307
71308
71309
71310
71311
71312
71313
71314
71315
71316
  UnpackedRecord r;
#endif /* local variables moved into u.bv */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bv.pC = p->apCsr[pOp->p1];
  assert( u.bv.pC!=0 );
  assert( u.bv.pC->isOrdered );
  if( ALWAYS(u.bv.pC->pCursor!=0) ){
    assert( u.bv.pC->deferredMoveto==0 );
    assert( pOp->p5==0 || pOp->p5==1 );
    assert( pOp->p4type==P4_INT32 );
    u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
    u.bv.r.nField = (u16)pOp->p4.i;
    if( pOp->p5 ){
      u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
    }else{
      u.bv.r.flags = UNPACKED_PREFIX_MATCH;
    }
    u.bv.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
    { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
#endif
    rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
    if( pOp->opcode==OP_IdxLT ){
      u.bv.res = -u.bv.res;
    }else{
      assert( pOp->opcode==OP_IdxGE );
      u.bv.res++;
    }
    if( u.bv.res>0 ){
      pc = pOp->p2 - 1 ;
    }
  }
  break;
}

/* Opcode: Destroy P1 P2 P3 * *
**
** Delete an entire database table or index whose root page in the database







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

|

|
|
|
|
|
|
|
|
|
<







71264
71265
71266
71267
71268
71269
71270
71271
71272
71273
71274
71275
71276
71277
71278
71279
71280
71281
71282
71283
71284
71285
71286
71287
71288
71289
71290
71291
71292
71293
71294

71295
71296
71297
71298
71299
71300
71301
  UnpackedRecord r;
#endif /* local variables moved into u.bv */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bv.pC = p->apCsr[pOp->p1];
  assert( u.bv.pC!=0 );
  assert( u.bv.pC->isOrdered );
  assert( u.bv.pC->pCursor!=0);
  assert( u.bv.pC->deferredMoveto==0 );
  assert( pOp->p5==0 || pOp->p5==1 );
  assert( pOp->p4type==P4_INT32 );
  u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
  u.bv.r.nField = (u16)pOp->p4.i;
  if( pOp->p5 ){
    u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
  }else{
    u.bv.r.flags = UNPACKED_PREFIX_MATCH;
  }
  u.bv.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
  { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
#endif
  rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
  if( pOp->opcode==OP_IdxLT ){
    u.bv.res = -u.bv.res;
  }else{
    assert( pOp->opcode==OP_IdxGE );
    u.bv.res++;
  }
  if( u.bv.res>0 ){
    pc = pOp->p2 - 1 ;

  }
  break;
}

/* Opcode: Destroy P1 P2 P3 * *
**
** Delete an entire database table or index whose root page in the database
88450
88451
88452
88453
88454
88455
88456
88457
88458
88459
88460
88461
88462
88463
88464
    }else{
      pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
    }
    if( pKey ){
      assert( sqlite3KeyInfoIsWriteable(pKey) );
      for(i=0; i<nCol; i++){
        char *zColl = pIdx->azColl[i];
        if( zColl==0 ) zColl = "BINARY";
        pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
        pKey->aSortOrder[i] = pIdx->aSortOrder[i];
      }
      if( pParse->nErr ){
        sqlite3KeyInfoUnref(pKey);
      }else{
        pIdx->pKeyInfo = pKey;







|







88435
88436
88437
88438
88439
88440
88441
88442
88443
88444
88445
88446
88447
88448
88449
    }else{
      pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
    }
    if( pKey ){
      assert( sqlite3KeyInfoIsWriteable(pKey) );
      for(i=0; i<nCol; i++){
        char *zColl = pIdx->azColl[i];
        if( NEVER(zColl==0) ) zColl = "BINARY";
        pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
        pKey->aSortOrder[i] = pIdx->aSortOrder[i];
      }
      if( pParse->nErr ){
        sqlite3KeyInfoUnref(pKey);
      }else{
        pIdx->pKeyInfo = pKey;
94375
94376
94377
94378
94379
94380
94381
94382
94383
94384
94385
94386
94387
94388
94389
94390
94391
    if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
  }
  if( ipkTop ){
    sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
    sqlite3VdbeJumpHere(v, ipkBottom);
  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
  VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** A consecutive range of registers starting at regNewData contains the







<
|
<







94360
94361
94362
94363
94364
94365
94366

94367

94368
94369
94370
94371
94372
94373
94374
    if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
  }
  if( ipkTop ){
    sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
    sqlite3VdbeJumpHere(v, ipkBottom);
  }
  

  *pbMayReplace = seenReplace;

  VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** A consecutive range of registers starting at regNewData contains the
94419
94420
94421
94422
94423
94424
94425
94426

94427
94428
94429
94430
94431
94432
94433
    if( aRegIdx[i]==0 ) continue;
    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
    }
    sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
    pik_flags = 0;
    if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
    if( pIdx->autoIndex==2 && !HasRowid(pTab) && pParse->nested==0 ){

      pik_flags |= OPFLAG_NCHANGE;
    }
    if( pik_flags )  sqlite3VdbeChangeP5(v, pik_flags);
  }
  if( !HasRowid(pTab) ) return;
  regData = regNewData + 1;
  regRec = sqlite3GetTempReg(pParse);







|
>







94402
94403
94404
94405
94406
94407
94408
94409
94410
94411
94412
94413
94414
94415
94416
94417
    if( aRegIdx[i]==0 ) continue;
    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
    }
    sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
    pik_flags = 0;
    if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
    if( pIdx->autoIndex==2 && !HasRowid(pTab) ){
      assert( pParse->nested==0 );
      pik_flags |= OPFLAG_NCHANGE;
    }
    if( pik_flags )  sqlite3VdbeChangeP5(v, pik_flags);
  }
  if( !HasRowid(pTab) ) return;
  regData = regNewData + 1;
  regRec = sqlite3GetTempReg(pParse);
106088
106089
106090
106091
106092
106093
106094
106095
106096
106097

106098
106099
106100
106101
106102
106103
106104
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      int iThisCur = iIdxCur+i;
      assert( aRegIdx );
      if( (openAll || aRegIdx[i]>0)
       && iThisCur!=aiCurOnePass[0]
       && iThisCur!=aiCurOnePass[1]
      ){

        sqlite3VdbeAddOp3(v, OP_OpenWrite, iThisCur, pIdx->tnum, iDb);
        sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
        assert( pParse->nTab>iThisCur );
        VdbeComment((v, "%s", pIdx->zName));
        if( okOnePass && pPk && iThisCur==iDataCur ){
          sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak,
                               regKey, nKey);







<


>







106072
106073
106074
106075
106076
106077
106078

106079
106080
106081
106082
106083
106084
106085
106086
106087
106088
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      int iThisCur = iIdxCur+i;
      assert( aRegIdx );
      if( (openAll || aRegIdx[i]>0)

       && iThisCur!=aiCurOnePass[1]
      ){
        assert( iThisCur!=aiCurOnePass[0] );
        sqlite3VdbeAddOp3(v, OP_OpenWrite, iThisCur, pIdx->tnum, iDb);
        sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
        assert( pParse->nTab>iThisCur );
        VdbeComment((v, "%s", pIdx->zName));
        if( okOnePass && pPk && iThisCur==iDataCur ){
          sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak,
                               regKey, nKey);
109886
109887
109888
109889
109890
109891
109892

109893
109894
109895
109896
109897
109898
109899
       p->aConstraintUsage[i].argvIndex,
       p->aConstraintUsage[i].omit);
  }
  sqlite3DebugPrintf("  idxNum=%d\n", p->idxNum);
  sqlite3DebugPrintf("  idxStr=%s\n", p->idxStr);
  sqlite3DebugPrintf("  orderByConsumed=%d\n", p->orderByConsumed);
  sqlite3DebugPrintf("  estimatedCost=%g\n", p->estimatedCost);

}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX







>







109870
109871
109872
109873
109874
109875
109876
109877
109878
109879
109880
109881
109882
109883
109884
       p->aConstraintUsage[i].argvIndex,
       p->aConstraintUsage[i].omit);
  }
  sqlite3DebugPrintf("  idxNum=%d\n", p->idxNum);
  sqlite3DebugPrintf("  idxStr=%s\n", p->idxStr);
  sqlite3DebugPrintf("  orderByConsumed=%d\n", p->orderByConsumed);
  sqlite3DebugPrintf("  estimatedCost=%g\n", p->estimatedCost);
  sqlite3DebugPrintf("  estimatedRows=%lld\n", p->estimatedRows);
}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
112695
112696
112697
112698
112699
112700
112701

112702
112703
112704
112705
112706
112707
112708
    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
    if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
    pIdxInfo->idxStr = 0;
    pIdxInfo->idxNum = 0;
    pIdxInfo->needToFreeIdxStr = 0;
    pIdxInfo->orderByConsumed = 0;
    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;

    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
    if( rc ) goto whereLoopAddVtab_exit;
    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
    pNew->prereq = 0;
    mxTerm = -1;
    assert( pNew->nLSlot>=nConstraint );
    for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;







>







112680
112681
112682
112683
112684
112685
112686
112687
112688
112689
112690
112691
112692
112693
112694
    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
    if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
    pIdxInfo->idxStr = 0;
    pIdxInfo->idxNum = 0;
    pIdxInfo->needToFreeIdxStr = 0;
    pIdxInfo->orderByConsumed = 0;
    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
    pIdxInfo->estimatedRows = 25;
    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
    if( rc ) goto whereLoopAddVtab_exit;
    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
    pNew->prereq = 0;
    mxTerm = -1;
    assert( pNew->nLSlot>=nConstraint );
    for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
112754
112755
112756
112757
112758
112759
112760
112761
112762
112763
112764
112765
112766
112767
112768
112769
      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 = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
      /* TUNING: Every virtual table query returns 25 rows */
      pNew->nOut = 46;  assert( 46==sqlite3LogEst(25) );
      whereLoopInsert(pBuilder, pNew);
      if( pNew->u.vtab.needFree ){
        sqlite3_free(pNew->u.vtab.idxStr);
        pNew->u.vtab.needFree = 0;
      }
    }
  }  







<
|







112740
112741
112742
112743
112744
112745
112746

112747
112748
112749
112750
112751
112752
112753
112754
      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 = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);

      pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
      whereLoopInsert(pBuilder, pNew);
      if( pNew->u.vtab.needFree ){
        sqlite3_free(pNew->u.vtab.idxStr);
        pNew->u.vtab.needFree = 0;
      }
    }
  }  
113975
113976
113977
113978
113979
113980
113981


113982
113983
113984
113985
113986
113987
113988
113989
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      int iIndexCur;
      int op = OP_OpenRead;


      if( pWInfo->okOnePass && iIdxCur ){
        Index *pJ = pTabItem->pTab->pIndex;
        iIndexCur = iIdxCur;
        assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
        while( ALWAYS(pJ) && pJ!=pIx ){
          iIndexCur++;
          pJ = pJ->pNext;
        }







>
>
|







113960
113961
113962
113963
113964
113965
113966
113967
113968
113969
113970
113971
113972
113973
113974
113975
113976
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      int iIndexCur;
      int op = OP_OpenRead;
      /* iIdxCur is always set if to a positive value if ONEPASS is possible */
      assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
      if( pWInfo->okOnePass ){
        Index *pJ = pTabItem->pTab->pIndex;
        iIndexCur = iIdxCur;
        assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
        while( ALWAYS(pJ) && pJ!=pIx ){
          iIndexCur++;
          pJ = pJ->pNext;
        }
141053
141054
141055
141056
141057
141058
141059










141060
141061
141062
141063
141064
141065
141066
141067
141068
141069
141070
141071
141072
141073

141074
141075
141076
141077
141078
141079
141080

/* Size of hash table Rtree.aHash. This hash table is not expected to
** ever contain very many entries, so a fixed number of buckets is 
** used.
*/
#define HASHSIZE 128











/* 
** An rtree virtual-table object.
*/
struct Rtree {
  sqlite3_vtab base;
  sqlite3 *db;                /* Host database connection */
  int iNodeSize;              /* Size in bytes of each node in the node table */
  int nDim;                   /* Number of dimensions */
  int nBytesPerCell;          /* Bytes consumed per cell */
  int iDepth;                 /* Current depth of the r-tree structure */
  char *zDb;                  /* Name of database containing r-tree table */
  char *zName;                /* Name of r-tree table */ 
  RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ 
  int nBusy;                  /* Current number of users of this structure */


  /* List of nodes removed during a CondenseTree operation. List is
  ** linked together via the pointer normally used for hash chains -
  ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree 
  ** headed by the node (leaf nodes have RtreeNode.iNode==0).
  */
  RtreeNode *pDeleted;







>
>
>
>
>
>
>
>
>
>














>







141040
141041
141042
141043
141044
141045
141046
141047
141048
141049
141050
141051
141052
141053
141054
141055
141056
141057
141058
141059
141060
141061
141062
141063
141064
141065
141066
141067
141068
141069
141070
141071
141072
141073
141074
141075
141076
141077
141078

/* Size of hash table Rtree.aHash. This hash table is not expected to
** ever contain very many entries, so a fixed number of buckets is 
** used.
*/
#define HASHSIZE 128

/* The xBestIndex method of this virtual table requires an estimate of
** the number of rows in the virtual table to calculate the costs of
** various strategies. If possible, this estimate is loaded from the
** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum).
** Otherwise, if no sqlite_stat1 entry is available, use 
** RTREE_DEFAULT_ROWEST.
*/
#define RTREE_DEFAULT_ROWEST 1048576
#define RTREE_MIN_ROWEST         100

/* 
** An rtree virtual-table object.
*/
struct Rtree {
  sqlite3_vtab base;
  sqlite3 *db;                /* Host database connection */
  int iNodeSize;              /* Size in bytes of each node in the node table */
  int nDim;                   /* Number of dimensions */
  int nBytesPerCell;          /* Bytes consumed per cell */
  int iDepth;                 /* Current depth of the r-tree structure */
  char *zDb;                  /* Name of database containing r-tree table */
  char *zName;                /* Name of r-tree table */ 
  RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ 
  int nBusy;                  /* Current number of users of this structure */
  i64 nRowEst;                /* Estimated number of rows in this table */

  /* List of nodes removed during a CondenseTree operation. List is
  ** linked together via the pointer normally used for hash chains -
  ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree 
  ** headed by the node (leaf nodes have RtreeNode.iNode==0).
  */
  RtreeNode *pDeleted;
142258
142259
142260
142261
142262
142263
142264













142265
142266
142267
142268
142269
142270
142271
      assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) );
    }
  }

  rtreeRelease(pRtree);
  return rc;
}














/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to 
** least desirable):
**
**   idxNum     idxStr        Strategy







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







142256
142257
142258
142259
142260
142261
142262
142263
142264
142265
142266
142267
142268
142269
142270
142271
142272
142273
142274
142275
142276
142277
142278
142279
142280
142281
142282
      assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) );
    }
  }

  rtreeRelease(pRtree);
  return rc;
}

/*
** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
** extension is currently being used by a version of SQLite too old to
** support estimatedRows. In that case this function is a no-op.
*/
static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
#if SQLITE_VERSION_NUMBER>=3008002
  if( sqlite3_libversion_number()>=3008002 ){
    pIdxInfo->estimatedRows = nRow;
  }
#endif
}

/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to 
** least desirable):
**
**   idxNum     idxStr        Strategy
142294
142295
142296
142297
142298
142299
142300

142301
142302

142303
142304
142305
142306
142307
142308
142309
142310
142311
142312
142313
142314
142315
142316
142317
142318
142319
142320
142321
142322
142323
142324
142325
142326
142327

142328
142329

142330
142331
142332
142333
142334
142335
142336
**   ----------------------
**
** The second of each pair of bytes identifies the coordinate column
** to which the constraint applies. The leftmost coordinate column
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){

  int rc = SQLITE_OK;
  int ii;


  int iIdx = 0;
  char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
  memset(zIdxStr, 0, sizeof(zIdxStr));
  UNUSED_PARAMETER(tab);

  assert( pIdxInfo->idxStr==0 );
  for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];

    if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
      /* We have an equality constraint on the rowid. Use strategy 1. */
      int jj;
      for(jj=0; jj<ii; jj++){
        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
        pIdxInfo->aConstraintUsage[jj].omit = 0;
      }
      pIdxInfo->idxNum = 1;
      pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
      pIdxInfo->aConstraintUsage[jj].omit = 1;

      /* This strategy involves a two rowid lookups on an B-Tree structures
      ** and then a linear search of an R-Tree node. This should be 
      ** considered almost as quick as a direct rowid lookup (for which 
      ** sqlite uses an internal cost of 0.0).

      */ 
      pIdxInfo->estimatedCost = 10.0;

      return SQLITE_OK;
    }

    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
      u8 op;
      switch( p->op ){
        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;







>


>




<



















|
>

|
>







142305
142306
142307
142308
142309
142310
142311
142312
142313
142314
142315
142316
142317
142318
142319

142320
142321
142322
142323
142324
142325
142326
142327
142328
142329
142330
142331
142332
142333
142334
142335
142336
142337
142338
142339
142340
142341
142342
142343
142344
142345
142346
142347
142348
142349
142350
**   ----------------------
**
** The second of each pair of bytes identifies the coordinate column
** to which the constraint applies. The leftmost coordinate column
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  Rtree *pRtree = (Rtree*)tab;
  int rc = SQLITE_OK;
  int ii;
  i64 nRow;                       /* Estimated rows returned by this scan */

  int iIdx = 0;
  char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
  memset(zIdxStr, 0, sizeof(zIdxStr));


  assert( pIdxInfo->idxStr==0 );
  for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];

    if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
      /* We have an equality constraint on the rowid. Use strategy 1. */
      int jj;
      for(jj=0; jj<ii; jj++){
        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
        pIdxInfo->aConstraintUsage[jj].omit = 0;
      }
      pIdxInfo->idxNum = 1;
      pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
      pIdxInfo->aConstraintUsage[jj].omit = 1;

      /* This strategy involves a two rowid lookups on an B-Tree structures
      ** and then a linear search of an R-Tree node. This should be 
      ** considered almost as quick as a direct rowid lookup (for which 
      ** sqlite uses an internal cost of 0.0). It is expected to return
      ** a single row.
      */ 
      pIdxInfo->estimatedCost = 30.0;
      setEstimatedRows(pIdxInfo, 1);
      return SQLITE_OK;
    }

    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
      u8 op;
      switch( p->op ){
        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
142351
142352
142353
142354
142355
142356
142357
142358

142359


142360
142361
142362
142363
142364
142365
142366
  }

  pIdxInfo->idxNum = 2;
  pIdxInfo->needToFreeIdxStr = 1;
  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
    return SQLITE_NOMEM;
  }
  assert( iIdx>=0 );

  pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));


  return rc;
}

/*
** Return the N-dimensional volumn of the cell stored in *p.
*/
static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){







|
>
|
>
>







142365
142366
142367
142368
142369
142370
142371
142372
142373
142374
142375
142376
142377
142378
142379
142380
142381
142382
142383
  }

  pIdxInfo->idxNum = 2;
  pIdxInfo->needToFreeIdxStr = 1;
  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
    return SQLITE_NOMEM;
  }

  nRow = pRtree->nRowEst / (iIdx + 1);
  pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
  setEstimatedRows(pIdxInfo, nRow);

  return rc;
}

/*
** Return the N-dimensional volumn of the cell stored in *p.
*/
static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
143826
143827
143828
143829
143830
143831
143832































143833
143834
143835
143836
143837
143838
143839
  );
  if( zSql ){
    rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  return rc;
}
































static sqlite3_module rtreeModule = {
  0,                          /* iVersion */
  rtreeCreate,                /* xCreate - create a table */
  rtreeConnect,               /* xConnect - connect to an existing table */
  rtreeBestIndex,             /* xBestIndex - Determine search strategy */
  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */







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







143843
143844
143845
143846
143847
143848
143849
143850
143851
143852
143853
143854
143855
143856
143857
143858
143859
143860
143861
143862
143863
143864
143865
143866
143867
143868
143869
143870
143871
143872
143873
143874
143875
143876
143877
143878
143879
143880
143881
143882
143883
143884
143885
143886
143887
  );
  if( zSql ){
    rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  return rc;
}

/*
** This function populates the pRtree->nRowEst variable with an estimate
** of the number of rows in the virtual table. If possible, this is based
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
*/
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
  const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'";
  sqlite3_stmt *p;
  int rc;
  i64 nRow = 0;

  rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
  if( rc==SQLITE_OK ){
    sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC);
    if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
    rc = sqlite3_finalize(p);
  }else if( rc!=SQLITE_NOMEM ){
    rc = SQLITE_OK;
  }

  if( rc==SQLITE_OK ){
    if( nRow==0 ){
      pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
    }else{
      pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
    }
  }

  return rc;
}

static sqlite3_module rtreeModule = {
  0,                          /* iVersion */
  rtreeCreate,                /* xCreate - create a table */
  rtreeConnect,               /* xConnect - connect to an existing table */
  rtreeBestIndex,             /* xBestIndex - Determine search strategy */
  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
143912
143913
143914
143915
143916
143917
143918

143919
143920
143921
143922
143923
143924
143925
  appStmt[3] = &pRtree->pReadRowid;
  appStmt[4] = &pRtree->pWriteRowid;
  appStmt[5] = &pRtree->pDeleteRowid;
  appStmt[6] = &pRtree->pReadParent;
  appStmt[7] = &pRtree->pWriteParent;
  appStmt[8] = &pRtree->pDeleteParent;


  for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
    char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
    if( zSql ){
      rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); 
    }else{
      rc = SQLITE_NOMEM;
    }







>







143960
143961
143962
143963
143964
143965
143966
143967
143968
143969
143970
143971
143972
143973
143974
  appStmt[3] = &pRtree->pReadRowid;
  appStmt[4] = &pRtree->pWriteRowid;
  appStmt[5] = &pRtree->pDeleteRowid;
  appStmt[6] = &pRtree->pReadParent;
  appStmt[7] = &pRtree->pWriteParent;
  appStmt[8] = &pRtree->pDeleteParent;

  rc = rtreeQueryStat1(db, pRtree);
  for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
    char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
    if( zSql ){
      rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); 
    }else{
      rc = SQLITE_NOMEM;
    }
Changes to SQLite.Interop/src/core/sqlite3.h.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
#define SQLITE_SOURCE_ID      "2013-11-11 01:42:10 aaed7d1d3ba0aef9f99fb157d3704b9f279aef71"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
#define SQLITE_SOURCE_ID      "2013-11-11 19:56:35 f58d57017199421167dae8ebc67db2f19be45082"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
5291
5292
5293
5294
5295
5296
5297
5298

5299

5300
5301










5302
5303
5304
5305
5306
5307
5308
** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
** ^The estimatedCost value is an estimate of the cost of doing the

** particular lookup.  A full scan of a table with N entries should have

** a cost of N.  A binary search of a table of N entries should have a
** cost of approximately log(N).










*/
struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column on left-hand side of constraint */
     unsigned char op;         /* Constraint operator */







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







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
** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
** ^The estimatedCost value is an estimate of the cost of a particular
** strategy. A cost of N indicates that the cost of the strategy is similar
** to a linear scan of an SQLite table with N rows. A cost of log(N) 
** indicates that the expense of the operation is similar to that of a
** binary search on a unique indexed field of an SQLite table with N rows.
**
** ^The estimatedRows value is an estimate of the number of rows that
** will be returned by the strategy.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite version 3.8.2. If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting 
** to read or write the estimatedRows field are undefined (but are likely 
** to included crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column on left-hand side of constraint */
     unsigned char op;         /* Constraint operator */
5319
5320
5321
5322
5323
5324
5325
5326

5327
5328
5329
5330
5331
5332
5333
    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;      /* Estimated cost of using this index */

};

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents







|
>







5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;           /* Estimated cost of using this index */
  sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
};

/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
** [sqlite3_index_info].aConstraint[].op field.  Each value represents
Changes to System.Data.SQLite/SQLiteModule.cs.
961
962
963
964
965
966
967


















968
969
970
971
972
973
974
        {
            constraintUsages = new SQLiteIndexConstraintUsage[nConstraint];
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////



















        #region Public Properties
        private SQLiteIndexConstraintUsage[] constraintUsages;
        /// <summary>
        /// An array of <see cref="SQLiteIndexConstraintUsage" /> object
        /// instances, each containing information to be supplied to the SQLite
        /// core library.
        /// </summary>







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







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
        {
            constraintUsages = new SQLiteIndexConstraintUsage[nConstraint];
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Determines if the native estimatedRows field can be used, based on
        /// the available version of the SQLite core library.
        /// </summary>
        /// <returns>
        /// Non-zero if the <see cref="EstimatedRows" /> property is supported
        /// by the SQLite core library.
        /// </returns>
        public bool CanUseEstimatedRows()
        {
            if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3008002)
                return true;

            return false;
        }

        ///////////////////////////////////////////////////////////////////////

        #region Public Properties
        private SQLiteIndexConstraintUsage[] constraintUsages;
        /// <summary>
        /// An array of <see cref="SQLiteIndexConstraintUsage" /> object
        /// instances, each containing information to be supplied to the SQLite
        /// core library.
        /// </summary>
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
        /// indicates that a default estimated cost value should be used.
        /// </summary>
        public double? EstimatedCost
        {
            get { return estimatedCost; }
            set { estimatedCost = value; }
        }













        #endregion
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteIndex Helper Class
    /// <summary>
    /// This class represents the various inputs and outputs used with the
    /// <see cref="ISQLiteManagedModule.BestIndex" /> method.
    /// </summary>
    public sealed class SQLiteIndex
    {
        #region Private Constants
        /// <summary>
        /// The default estimated cost for use with the
        /// <see cref="ISQLiteManagedModule.BestIndex" /> method.
        /// </summary>
        internal static readonly double DefaultEstimatedCost = double.MaxValue;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Internal Constructors
        /// <summary>
        /// Constructs an instance of this class.
        /// </summary>
        /// <param name="nConstraint">
        /// The number of <see cref="SQLiteIndexConstraint" /> (and
        /// <see cref="SQLiteIndexConstraintUsage" />) instances to







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













<
<
<
<
<
<
<
<
<
<







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
        /// indicates that a default estimated cost value should be used.
        /// </summary>
        public double? EstimatedCost
        {
            get { return estimatedCost; }
            set { estimatedCost = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private long? estimatedRows;
        /// <summary>
        /// Estimated number of rows returned.  Using a null value here
        /// indicates that a default estimated rows value should be used.
        /// </summary>
        public long? EstimatedRows
        {
            get { return estimatedRows; }
            set { estimatedRows = value; }
        }
        #endregion
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteIndex Helper Class
    /// <summary>
    /// This class represents the various inputs and outputs used with the
    /// <see cref="ISQLiteManagedModule.BestIndex" /> method.
    /// </summary>
    public sealed class SQLiteIndex
    {










        #region Internal Constructors
        /// <summary>
        /// Constructs an instance of this class.
        /// </summary>
        /// <param name="nConstraint">
        /// The number of <see cref="SQLiteIndexConstraint" /> (and
        /// <see cref="SQLiteIndexConstraintUsage" />) instances to
1265
1266
1267
1268
1269
1270
1271


1272
1273








1274
1275
1276
1277
1278
1279
1280

            SQLiteMarshal.WriteInt32(pIndex, offset,
                index.Outputs.OrderByConsumed);

            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
                sizeof(double));



            SQLiteMarshal.WriteDouble(pIndex, offset,
                index.Outputs.EstimatedCost.GetValueOrDefault());








        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Properties
        private SQLiteIndexInputs inputs;







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







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

            SQLiteMarshal.WriteInt32(pIndex, offset,
                index.Outputs.OrderByConsumed);

            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
                sizeof(double));

            if (index.Outputs.EstimatedCost.HasValue)
            {
                SQLiteMarshal.WriteDouble(pIndex, offset,
                    index.Outputs.EstimatedCost.GetValueOrDefault());
            }

            if (index.Outputs.CanUseEstimatedRows() &&
                index.Outputs.EstimatedRows.HasValue)
            {
                SQLiteMarshal.WriteInt64(pIndex, offset,
                    index.Outputs.EstimatedRows.GetValueOrDefault());
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Properties
        private SQLiteIndexInputs inputs;
4411
4412
4413
4414
4415
4416
4417






























4418
4419
4420
4421
4422
4423
4424
#else
            Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value);
#endif
        }

        ///////////////////////////////////////////////////////////////////////































        /// <summary>
        /// Writes a <see cref="Double" /> value to the specified memory
        /// location.
        /// </summary>
        /// <param name="pointer">
        /// The <see cref="IntPtr" /> object instance representing the base
        /// memory location.







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







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
#else
            Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value);
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Writes an <see cref="Int64" /> value to the specified memory
        /// location.
        /// </summary>
        /// <param name="pointer">
        /// The <see cref="IntPtr" /> object instance representing the base
        /// memory location.
        /// </param>
        /// <param name="offset">
        /// The integer offset from the base memory location where the
        /// <see cref="Int64" /> value to be written is located.
        /// </param>
        /// <param name="value">
        /// The <see cref="Int64" /> value to write.
        /// </param>
        public static void WriteInt64(
            IntPtr pointer,
            int offset,
            long value
            )
        {
#if !PLATFORM_COMPACTFRAMEWORK
            Marshal.WriteInt64(pointer, offset, value);
#else
            Marshal.WriteInt64(IntPtrForOffset(pointer, offset), value);
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Writes a <see cref="Double" /> value to the specified memory
        /// location.
        /// </summary>
        /// <param name="pointer">
        /// The <see cref="IntPtr" /> object instance representing the base
        /// memory location.
6837
6838
6839
6840
6841
6842
6843
6844

6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the specified estimated cost.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <param name="estimatedCost">
        /// The estimated cost value to use.

        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedCost(
            SQLiteIndex index,
            double estimatedCost
            )
        {
            if ((index == null) || (index.Outputs == null))
                return false;

            index.Outputs.EstimatedCost = estimatedCost;
            return true;







|
>






|







6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the specified estimated cost.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <param name="estimatedCost">
        /// The estimated cost value to use.  Using a null value means that the
        /// default value provided by the SQLite core library should be used.
        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedCost(
            SQLiteIndex index,
            double? estimatedCost
            )
        {
            if ((index == null) || (index.Outputs == null))
                return false;

            index.Outputs.EstimatedCost = estimatedCost;
            return true;
6870
6871
6872
6873
6874
6875
6876
6877















































6878
6879
6880
6881
6882
6883
6884
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedCost(
            SQLiteIndex index
            )
        {
            return SetEstimatedCost(index, SQLiteIndex.DefaultEstimatedCost);















































        }
        #endregion
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Properties







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







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
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedCost(
            SQLiteIndex index
            )
        {
            return SetEstimatedCost(index, null);
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the specified estimated rows.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <param name="estimatedRows">
        /// The estimated rows value to use.  Using a null value means that the
        /// default value provided by the SQLite core library should be used.
        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedRows(
            SQLiteIndex index,
            long? estimatedRows
            )
        {
            if ((index == null) || (index.Outputs == null))
                return false;

            index.Outputs.EstimatedRows = estimatedRows;
            return true;
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Modifies the specified <see cref="SQLiteIndex" /> object instance
        /// to contain the default estimated rows.
        /// </summary>
        /// <param name="index">
        /// The <see cref="SQLiteIndex" /> object instance to modify.
        /// </param>
        /// <returns>
        /// Non-zero upon success.
        /// </returns>
        protected virtual bool SetEstimatedRows(
            SQLiteIndex index
            )
        {
            return SetEstimatedRows(index, null);
        }
        #endregion
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Public Properties