SQLite

Check-in [a54aef35da]
Login

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

Overview
Comment:Add the sqlite3_whereinfo_hook() API - an experimental API replacing the DBCONFIG_WHEREINFO hack on this branch.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | schemalint
Files: files | file ages | folders
SHA3-256: a54aef35da11f7508a8888a159372036a362fc52afa1df752dc835db334c4330
User & Date: dan 2017-04-04 04:23:06.108
Context
2017-04-04
17:50
Add some support for OR terms to sqlite3_whereinfo_hook(). (check-in: 5cd070000d user: dan tags: schemalint)
04:23
Add the sqlite3_whereinfo_hook() API - an experimental API replacing the DBCONFIG_WHEREINFO hack on this branch. (check-in: a54aef35da user: dan tags: schemalint)
2017-03-31
11:20
Merge latest trunk into this branch. (check-in: cb721d0b36 user: dan tags: schemalint)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
    case SQLITE_DBCONFIG_LOOKASIDE: {
      void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
      int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
      int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
      rc = setupLookaside(db, pBuf, sz, cnt);
      break;
    }
#ifdef SQLITE_SCHEMA_LINT
    case SQLITE_DBCONFIG_WHEREINFO: {
      db->xWhereInfo = va_arg(ap, void(*)(void*, int, const char*, int, i64));
      db->pWhereInfoCtx = va_arg(ap, void*);
      break;
    }
#endif
    default: {
      static const struct {
        int op;      /* The opcode */
        u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
      } aFlagOp[] = {
        { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
        { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },







<
<
<
<
<
<
<







797
798
799
800
801
802
803







804
805
806
807
808
809
810
    case SQLITE_DBCONFIG_LOOKASIDE: {
      void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
      int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
      int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
      rc = setupLookaside(db, pBuf, sz, cnt);
      break;
    }







    default: {
      static const struct {
        int op;      /* The opcode */
        u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
      } aFlagOp[] = {
        { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
        { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
1999
2000
2001
2002
2003
2004
2005




















2006
2007
2008
2009
2010
2011
2012
  pRet = db->pPreUpdateArg;
  db->xPreUpdateCallback = xCallback;
  db->pPreUpdateArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */





















#ifndef SQLITE_OMIT_WAL
/*
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
** is greater than sqlite3.pWalArg cast to an integer (the value configured by
** wal_autocheckpoint()).







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







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
  pRet = db->pPreUpdateArg;
  db->xPreUpdateCallback = xCallback;
  db->pPreUpdateArg = pArg;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */

#ifdef SQLITE_ENABLE_WHEREINFO_HOOK
/*
** Register a where-info hook.
*/
void *sqlite3_whereinfo_hook(
  sqlite3 *db,                    /* Register callback with this db handle */
  void (*xWhereInfo)(void*, int, const char*, int, sqlite3_uint64),
  void *pCtx                      /* User pointer passed to callback */
){
  void *pRet;
  sqlite3_mutex_enter(db->mutex);
  pRet = db->pWhereInfoCtx;
  db->xWhereInfo = xWhereInfo;
  db->pWhereInfoCtx = pCtx;
  sqlite3_mutex_leave(db->mutex);
  return pRet;
}
#endif /* SQLITE_ENABLE_WHEREINFO_HOOK */


#ifndef SQLITE_OMIT_WAL
/*
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
** is greater than sqlite3.pWalArg cast to an integer (the value configured by
** wal_autocheckpoint()).
Changes to src/shell_indexes.c.
8
9
10
11
12
13
14

15
16
17
18
19
20
21
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
*/

typedef sqlite3_int64 i64;


typedef struct IdxConstraint IdxConstraint;
typedef struct IdxContext IdxContext;
typedef struct IdxScan IdxScan;
typedef struct IdxWhere IdxWhere;

typedef struct IdxColumn IdxColumn;







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
*/

typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;

typedef struct IdxConstraint IdxConstraint;
typedef struct IdxContext IdxContext;
typedef struct IdxScan IdxScan;
typedef struct IdxWhere IdxWhere;

typedef struct IdxColumn IdxColumn;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
** SQLITE_DBCONFIG_WHEREINFO callback.
*/
static void idxWhereInfo(
  void *pCtx,                     /* Pointer to IdxContext structure */
  int eOp, 
  const char *zVal, 
  int iVal, 
  i64 mask
){
  IdxContext *p = (IdxContext*)pCtx;

#if 0
  const char *zOp = 
    eOp==SQLITE_WHEREINFO_TABLE ? "TABLE" :
    eOp==SQLITE_WHEREINFO_EQUALS ? "EQUALS" :







|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
** SQLITE_DBCONFIG_WHEREINFO callback.
*/
static void idxWhereInfo(
  void *pCtx,                     /* Pointer to IdxContext structure */
  int eOp, 
  const char *zVal, 
  int iVal, 
  u64 mask
){
  IdxContext *p = (IdxContext*)pCtx;

#if 0
  const char *zOp = 
    eOp==SQLITE_WHEREINFO_TABLE ? "TABLE" :
    eOp==SQLITE_WHEREINFO_EQUALS ? "EQUALS" :
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
        }

        sqlite3_bind_int64(p->pInsertMask, 1, mask);
        sqlite3_step(p->pInsertMask);
        p->rc = sqlite3_reset(p->pInsertMask);
        break;
      }

      case SQLITE_WHEREINFO_BEGINOR: {
        IdxWhere *pNew = (IdxWhere*)idxMalloc(&p->rc, sizeof(IdxWhere));
        if( pNew==0 ) return;
        pNew->pParent = p->pCurrent;
        pNew->pNextOr = p->pCurrent->pOr;
        p->pCurrent->pOr = pNew;
        p->pCurrent = pNew;
        break;
      }

      case SQLITE_WHEREINFO_NEXTOR: {
        IdxWhere *pNew = (IdxWhere*)idxMalloc(&p->rc, sizeof(IdxWhere));
        if( pNew==0 ) return;
        pNew->pParent = p->pCurrent->pParent;
        assert( p->pCurrent->pSibling==0 );
        p->pCurrent->pSibling = pNew;
        p->pCurrent = pNew;
        break;
      }

      case SQLITE_WHEREINFO_ENDOR: {
        assert( p->pCurrent->pParent );
        p->pCurrent = p->pCurrent->pParent;
        break;
      }
    }
  }
}

/*
** An error associated with database handle db has just occurred. Pass
** the error message to callback function xOut.







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







230
231
232
233
234
235
236


























237
238
239
240
241
242
243
        }

        sqlite3_bind_int64(p->pInsertMask, 1, mask);
        sqlite3_step(p->pInsertMask);
        p->rc = sqlite3_reset(p->pInsertMask);
        break;
      }


























    }
  }
}

/*
** An error associated with database handle db has just occurred. Pass
** the error message to callback function xOut.
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
        "INSERT OR IGNORE INTO aux.depmask SELECT mask | ?1 FROM aux.depmask;"
    );
  }

  /* Analyze the SELECT statement in zSql. */
  if( rc==SQLITE_OK ){
    ctx.dbm = dbm;
    sqlite3_db_config(db, SQLITE_DBCONFIG_WHEREINFO, idxWhereInfo, (void*)&ctx);
    rc = idxPrepareStmt(db, &pStmt, pzErrmsg, zSql);
    sqlite3_db_config(db, SQLITE_DBCONFIG_WHEREINFO, (void*)0, (void*)0);
    sqlite3_finalize(pStmt);
  }

  /* Create tables within the main in-memory database. These tables
  ** have the same names, columns and declared types as the tables in
  ** the user database. All constraints except for PRIMARY KEY are
  ** removed. */







|

|







925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
        "INSERT OR IGNORE INTO aux.depmask SELECT mask | ?1 FROM aux.depmask;"
    );
  }

  /* Analyze the SELECT statement in zSql. */
  if( rc==SQLITE_OK ){
    ctx.dbm = dbm;
    sqlite3_whereinfo_hook(db, idxWhereInfo, (void*)&ctx);
    rc = idxPrepareStmt(db, &pStmt, pzErrmsg, zSql);
    sqlite3_whereinfo_hook(db, 0, 0);
    sqlite3_finalize(pStmt);
  }

  /* Create tables within the main in-memory database. These tables
  ** have the same names, columns and declared types as the tables in
  ** the user database. All constraints except for PRIMARY KEY are
  ** removed. */
Changes to src/sqlite.h.in.
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
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */

#define SQLITE_DBCONFIG_WHEREINFO             1007  /* xWhereInfo void* */

#define SQLITE_WHEREINFO_TABLE   1
#define SQLITE_WHEREINFO_EQUALS  2
#define SQLITE_WHEREINFO_RANGE   3
#define SQLITE_WHEREINFO_ORDERBY 4
#define SQLITE_WHEREINFO_BEGINOR 5
#define SQLITE_WHEREINFO_ENDOR   6
#define SQLITE_WHEREINFO_NEXTOR  7


/*
** CAPI3REF: Enable Or Disable Extended Result Codes
** METHOD: sqlite3
**
** ^The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. ^The extended result







<
<
<
<
<
<
<
<
<
<
<







2012
2013
2014
2015
2016
2017
2018











2019
2020
2021
2022
2023
2024
2025
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */












/*
** CAPI3REF: Enable Or Disable Extended Result Codes
** METHOD: sqlite3
**
** ^The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. ^The extended result
8492
8493
8494
8495
8496
8497
8498













































































































































8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
** transaction open on the database, or if the database is not a wal mode
** database.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);














































































































































/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif /* SQLITE3_H */







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












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
** transaction open on the database, or if the database is not a wal mode
** database.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);

/*
** This function is used to register a whereinfo hook with the database
** handle passed as the first argument. Once registered, the whereinfo hook
** is invoked zero or more times while preparing a query to provide
** information to the application. It is intended to be used by expert 
** systems to recommend indexes that could be added to the database in order
** to improve query response time.
**
** An SQLite query plan describes the way data is read from zero or more
** database tables. For each table read, the data required may be
** constrained by equality or range constraints on one or more columns, 
** and it may or may not be required in order sorted by one or more 
** columns. For example, the following query:
**
** <pre>
**     SELECT * FROM t1 WHERE t1.a = ? ORDER BY t1.b;
** </pre>
**
** reads data from table t1. It requires only those rows for which t1.a
** is set to a specific value, and requires them sorted in order of
** column t1.b. Internally, SQLite determines this and attempts to locate
** an index that can be used to efficiently find the required subset of
** rows and/or allows the rows to be read from the database in the 
** required order. In this case, ideally an index of the form:
**
** <pre>
**     CREATE INDEX i1 ON t1(a, b);
** </pre>
**
** The data passed to the whereinfo hook during query preparation do
** not describe the actual query plan to the application. Instead, it
** describes the parts of the query that SQLite could use an index to
** optimize if a suitable index existed. In this case, that only
** rows with t1.a=? are required, and that they are required sorted
** in order by t1.b.
**
** Each time the whereinfo hook is invoked, the first argument is a
** copy of the (void*) pointer passed as the second argument to this
** API function. The second is always one of the SQLITE_WHEREINFO_XXX
** constants defined below.
**
** For each table read by a query, the whereinfo hook is invoked as follows:
**
** <ul>
**   <li> Once with SQLITE_WHEREINFO_TABLE as the second argument. This
**        indicates the table that subsequent callbacks (until the next
**        SQLITE_WHEREINFO_TABLE) apply to.
**
**   <li> If SQLite requires rows in a specific order, once with
**        SQLITE_WHEREINFO_ORDERBY for each column of the table that is
**        one of the sort keys.
**
**   <li> If there are any "<col> = ?" constraints that restrict the rows
**        required by SQLite, once with SQLITE_WHEREINFO_EQUALS for each
**        such constraint.
**
**   <li> If there are any "<col> > ?" constraints (or any other range
**        constraint) that restrict the rows required by SQLite, once with 
**        SQLITE_WHEREINFO_RANGE for each such constraint.
** </ul>
**
** The third, fourth and fifth arguments passed to the whereinfo callback
** are interpreted differently, depending on the SQLITE_WHEREINFO_XXX value
** as follows:
**
** <dl>
**   <dt> SQLITE_WHEREINFO_TABLE
**   <dd> The third argument passed in this case is the name of the table.
**        The fourth is the index of the database in which the table is
**        located (0 for "main", 1 for "temp" or higher for an attached
**        database). The fifth argument is a bitmask that indicates which
**        of the tables columns may be required by the query. If the leftmost
**        column of the table is used in some way, bit 0 of the bitmask is
**        set. If the next-to-leftmost is used, bit 1 etc. Bit 63 is used to
**        represent all columns with an index of 63 or higher. If bit 63
**        is set, the application should assume that the query requires all
**        columns from the table with an index of 63 or greater.
**
**   <dt> SQLITE_WHEREINFO_ORDERBY
**   <dd> The third argument passed in this case is the name of the collation
**        sequence to sort by. The fourth is the index of the table column to
**        sort by (0 for the leftmost column, 1 for the next-to-leftmost
**        etc.). The fifth argument is a boolean flag - true for a DESC sort
**        or false for ASC.
**
**   <dt> SQLITE_WHEREINFO_EQUALS
**   <dd> The third argument passed in this case is the name of the collation
**        sequence used by the constraint. The fourth is the index of the 
**        table column in the constraint. If the current table is not part
**        of a join, then the value passed as the fifth argument is always
**        zero. Or, if it is part of a join, then the fifth parameter passed
**        to this callback is a mask of other tables that the current
**        constraint depends on. For example, in the query:
**
**   <pre>
**      SELECT * FROM t1, t2 WHERE t1.a = (t2.b+1);
**   </pre>
**
**        the fifth parameter passed to the the SQLITE_WHEREINFO_EQUALS
**        whereinfo callback would have the bit assigned to table "t2"
**        set to true. There is no way for the application to determine 
**        the specific bit in the mask assigned to any table, but the bit
**        assignments are consistent while parsing a single query.
**
**   <dt> SQLITE_WHEREINFO_RANGE
**   <dd> As for SQLITE_WHEREINFO_EQUALS.
** </dl>
**
** Note that if a WHERE clause includes an OR expression, then there may be
** more than one set of callbacks for a single table. For example, the
** following SQL:
**
** <pre>
**    SELECT * FROM t1 WHERE t1.a=? OR t1.b=?
** </pre>
**
** Provokes the same callbacks as the following two queries executed in
** series.
**
** <pre>
**    SELECT * FROM t1 WHERE t1.a=?;
**    SELECT * FROM t1 WHERE t1.b=?;
** </pre>
*/
SQLITE_EXPERIMENTAL void *sqlite3_whereinfo_hook(
  sqlite3 *db,                    /* Register callback with this db handle */
  void (*xWhereInfo)(
    void*,                        /* Copy of pCtx */
    int,                          /* SQLITE_WHEREINFO_XXX constant */
    const char*,
    int,
    sqlite3_uint64
  ),
  void *pCtx                      /* User pointer passed to callback */
);

#define SQLITE_WHEREINFO_TABLE   1
#define SQLITE_WHEREINFO_EQUALS  2
#define SQLITE_WHEREINFO_RANGE   3
#define SQLITE_WHEREINFO_ORDERBY 4

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif /* SQLITE3_H */
Changes to src/sqliteInt.h.
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
  void *pUnlockArg;                     /* Argument to xUnlockNotify */
  void (*xUnlockNotify)(void **, int);  /* Unlock notify callback */
  sqlite3 *pNextBlocked;        /* Next in list of all blocked connections */
#endif
#ifdef SQLITE_USER_AUTHENTICATION
  sqlite3_userauth auth;        /* User authentication information */
#endif
#ifdef SQLITE_SCHEMA_LINT
  void (*xWhereInfo)(void*, int, const char*, int, i64);
  void *pWhereInfoCtx;
#endif
};

/*
** A macro to discover the encoding of a database.
*/







|
|







1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
  void *pUnlockArg;                     /* Argument to xUnlockNotify */
  void (*xUnlockNotify)(void **, int);  /* Unlock notify callback */
  sqlite3 *pNextBlocked;        /* Next in list of all blocked connections */
#endif
#ifdef SQLITE_USER_AUTHENTICATION
  sqlite3_userauth auth;        /* User authentication information */
#endif
#ifdef SQLITE_ENABLE_WHEREINFO_HOOK
  void (*xWhereInfo)(void*, int, const char*, int, u64);
  void *pWhereInfoCtx;
#endif
};

/*
** A macro to discover the encoding of a database.
*/
Changes to src/where.c.
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
  WhereTerm *pTerm, *pWCEnd;
  int rc = SQLITE_OK;
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  struct SrcList_item *pItem;
  
  pWC = pBuilder->pWC;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_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;
    
      sSubBuild = *pBuilder;
      sSubBuild.pOrderBy = 0;
      sSubBuild.pOrSet = &sCur;

      WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        if( (pOrTerm->eOperator & WO_AND)!=0 ){







|
















|







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
  WhereTerm *pTerm, *pWCEnd;
  int rc = SQLITE_OK;
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  struct SrcList_item *pItem;

  pWC = pBuilder->pWC;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_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;

      sSubBuild = *pBuilder;
      sSubBuild.pOrderBy = 0;
      sSubBuild.pOrSet = &sCur;

      WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        if( (pOrTerm->eOperator & WO_AND)!=0 ){
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
    pLoop->cId = '0';
#endif
    return 1;
  }
  return 0;
}

#ifdef SQLITE_SCHEMA_LINT
static void whereTraceWC(
  Parse *pParse, 
  struct SrcList_item *pItem,
  WhereClause *pWC,
  int bOr
){
  sqlite3 *db = pParse->db;
  Table *pTab = pItem->pTab;
  void (*x)(void*, int, const char*, int, i64) = db->xWhereInfo;
  void *pCtx = db->pWhereInfoCtx;
  int bFirst = 1;                 /* True until first callback is made */
  int ii;

  /* Issue callbacks for WO_SINGLE constraints */
  for(ii=0; ii<pTab->nCol; ii++){
    int opMask = WO_SINGLE; 
    WhereScan scan;
    WhereTerm *pTerm;
    for(pTerm=whereScanInit(&scan, pWC, pItem->iCursor, ii, opMask, 0);
        pTerm;
        pTerm=whereScanNext(&scan)
    ){
      int eOp;
      Expr *pX = pTerm->pExpr;
      CollSeq *pC = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
      if( pTerm->eOperator & (WO_IS|WO_EQ|WO_IN) ){
        eOp = SQLITE_WHEREINFO_EQUALS;
      }else{
        eOp = SQLITE_WHEREINFO_RANGE;
      }
      if( bOr && !bFirst ) x(pCtx, SQLITE_WHEREINFO_NEXTOR, 0, 0, 0);
      x(pCtx, eOp, (pC ? pC->zName : "BINARY"), ii, pTerm->prereqRight);
      bFirst = 0;
    }
  }

  /* Callbacks for composite - (WO_OR|WO_AND) - constraints */
  for(ii=0; ii<pWC->nTerm; ii++){
    WhereTerm *pTerm = &pWC->a[ii];
    if( pTerm->eOperator & WO_OR ){
      assert( bOr==0 );
      x(pCtx, SQLITE_WHEREINFO_BEGINOR, 0, 0, 0);
      whereTraceWC(pParse, pItem, &pTerm->u.pOrInfo->wc, 1);
      x(pCtx, SQLITE_WHEREINFO_ENDOR, 0, 0, 0);
    }
    if( pTerm->eOperator & WO_AND ){
      if( bOr && !bFirst ) x(pCtx, SQLITE_WHEREINFO_NEXTOR, 0, 0, 0);
      whereTraceWC(pParse, pItem, &pTerm->u.pAndInfo->wc, 0);
      bFirst = 0;
    }
  }
}





static void whereTraceBuilder(
  Parse *pParse,
  WhereLoopBuilder *p
){
  sqlite3 *db = pParse->db;
  if( db->xWhereInfo && db->init.busy==0 ){
    void (*x)(void*, int, const char*, int, i64) = db->xWhereInfo;







|



|
<





<



















<

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




|
>
>
>







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
    pLoop->cId = '0';
#endif
    return 1;
  }
  return 0;
}

#ifdef SQLITE_ENABLE_WHEREINFO_HOOK
static void whereTraceWC(
  Parse *pParse, 
  struct SrcList_item *pItem,
  WhereClause *pWC

){
  sqlite3 *db = pParse->db;
  Table *pTab = pItem->pTab;
  void (*x)(void*, int, const char*, int, i64) = db->xWhereInfo;
  void *pCtx = db->pWhereInfoCtx;

  int ii;

  /* Issue callbacks for WO_SINGLE constraints */
  for(ii=0; ii<pTab->nCol; ii++){
    int opMask = WO_SINGLE; 
    WhereScan scan;
    WhereTerm *pTerm;
    for(pTerm=whereScanInit(&scan, pWC, pItem->iCursor, ii, opMask, 0);
        pTerm;
        pTerm=whereScanNext(&scan)
    ){
      int eOp;
      Expr *pX = pTerm->pExpr;
      CollSeq *pC = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
      if( pTerm->eOperator & (WO_IS|WO_EQ|WO_IN) ){
        eOp = SQLITE_WHEREINFO_EQUALS;
      }else{
        eOp = SQLITE_WHEREINFO_RANGE;
      }

      x(pCtx, eOp, (pC ? pC->zName : "BINARY"), ii, pTerm->prereqRight);

















    }
  }
}

/*
** If there is a where-info hook attached to the database handle, issue all
** required callbacks for the current sqlite3WhereBegin() call.
*/
static void whereTraceBuilder(
  Parse *pParse,
  WhereLoopBuilder *p
){
  sqlite3 *db = pParse->db;
  if( db->xWhereInfo && db->init.busy==0 ){
    void (*x)(void*, int, const char*, int, i64) = db->xWhereInfo;
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

        /* Table name callback */
        x(pCtx, SQLITE_WHEREINFO_TABLE, pTab->zName, iDb, pItem->colUsed);

        /* ORDER BY callbacks */
        if( p->pOrderBy ){
          int i;
          int bFirst = 1;
          for(i=0; i<p->pOrderBy->nExpr; i++){
            Expr *pExpr = p->pOrderBy->a[i].pExpr; 
            CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
            pExpr = sqlite3ExprSkipCollate(pExpr);
            if( pExpr->op==TK_COLUMN && pExpr->iTable==pItem->iCursor ){
              int iCol = pExpr->iColumn;
              if( pColl && iCol>=0 ){
                int bDesc = p->pOrderBy->a[i].sortOrder;
                x(pCtx, SQLITE_WHEREINFO_ORDERBY, pColl->zName, iCol, bDesc); 
              }
            }
          }
        }

        /* WHERE callbacks */
        whereTraceWC(pParse, pItem, p->pWC, 0);
      }
    }
  }
}
#else
# define whereTraceBuilder(x,y)
#endif







<















|







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

        /* Table name callback */
        x(pCtx, SQLITE_WHEREINFO_TABLE, pTab->zName, iDb, pItem->colUsed);

        /* ORDER BY callbacks */
        if( p->pOrderBy ){
          int i;

          for(i=0; i<p->pOrderBy->nExpr; i++){
            Expr *pExpr = p->pOrderBy->a[i].pExpr; 
            CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
            pExpr = sqlite3ExprSkipCollate(pExpr);
            if( pExpr->op==TK_COLUMN && pExpr->iTable==pItem->iCursor ){
              int iCol = pExpr->iColumn;
              if( pColl && iCol>=0 ){
                int bDesc = p->pOrderBy->a[i].sortOrder;
                x(pCtx, SQLITE_WHEREINFO_ORDERBY, pColl->zName, iCol, bDesc); 
              }
            }
          }
        }

        /* WHERE callbacks */
        whereTraceWC(pParse, pItem, p->pWC);
      }
    }
  }
}
#else
# define whereTraceBuilder(x,y)
#endif
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
    sqlite3DebugPrintf(")\n");
  }
  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
    sqlite3WhereClausePrint(sWLB.pWC);
  }
#endif

  /* Schema-lint xTrace callback */
  whereTraceBuilder(pParse, &sWLB);

  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
    rc = whereLoopAddAll(&sWLB);
    if( rc ) goto whereBeginError;
  
#ifdef WHERETRACE_ENABLED







|







4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
    sqlite3DebugPrintf(")\n");
  }
  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
    sqlite3WhereClausePrint(sWLB.pWC);
  }
#endif

  /* Invoke the where-info hook, if one has been registered. */
  whereTraceBuilder(pParse, &sWLB);

  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
    rc = whereLoopAddAll(&sWLB);
    if( rc ) goto whereBeginError;
  
#ifdef WHERETRACE_ENABLED