/ Changes On Branch cost-est
Login

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

Changes In Branch cost-est Excluding Merge-Ins

This is equivalent to a diff from 7be6222c9e to 9404300ac1

2019-04-27
20:39
Add the shardvtab virtual table that uses the new cost estimation functions. (Leaf check-in: 9404300ac1 user: drh tags: cost-est)
2019-04-26
17:20
An experimental interface for retrieving the estimated cost and estimated number of output rows for a query. (check-in: 1b25fa108a user: drh tags: cost-est)
17:08
Omit tests of the LIKE optimization in like3.test when SQLITE_ENABLE_ICU is defined. (check-in: af53c41a12 user: dan tags: trunk)
2019-04-25
20:06
Merge latest trunk changes into this branch. (check-in: 1da302d85d user: dan tags: dbdata)
18:15
Add the sqlite3_hard_heap_limit64() interface and the corresponding "PRAGMA hard_heap_limit=N" command. (check-in: b0ccef61a7 user: drh tags: hard-heap-limit)
2019-04-24
17:04
New test cases in test/fuzzdata8.db. (check-in: 7be6222c9e user: drh tags: trunk)
16:13
Fix another instance in fts3 where a corrupt record can cause a buffer overflow. (check-in: e1724f1d61 user: dan tags: trunk)

Added ext/misc/shardvtab.c.















































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/*
** 2019-04-26
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements a virtual-table that can be used to access a
** sharded table implemented as the UNION ALL of various separate tables.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#include <math.h>

/* shardvtab_vtab is a subclass of sqlite3_vtab which is
** underlying representation of the virtual table
*/
typedef struct shardvtab_vtab shardvtab_vtab;
struct shardvtab_vtab {
  sqlite3_vtab base;  /* Base class - must be first */
  sqlite3 *db;        /* The database connection */
  char *zView;        /* Name of view that implements the shard */
  int nCol;           /* Number of columns in the view */
  char **azCol;       /* Names of the columns, individually malloced */
};

/* shardvtab_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
typedef struct shardvtab_cursor shardvtab_cursor;
struct shardvtab_cursor {
  sqlite3_vtab_cursor base;  /* Base class - must be first */
  sqlite3_stmt *pStmt;       /* Prepared statement to access the shard */
  int rcLastStep;            /* Last return from sqlite3_step() */
};

/*
** The shardvtabConnect() method is invoked to create a new
** shard virtual table.
**
** Think of this routine as the constructor for shardvtab_vtab objects.
**
** All this routine needs to do is:
**
**    (1) Allocate the shardvtab_vtab object and initialize all fields.
**
**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
**        result set of queries against the virtual table will look like.
*/
static int shardvtabConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  shardvtab_vtab *pNew;
  int rc;
  char *zSql;
  sqlite3_str *pSchema;
  sqlite3_stmt *pStmt = 0;
  const char *zView = 0;
  char **azCol = 0;
  int nCol = 0;
  char cSep;
  int i;

  if( argc!=4 || argv[0]==0 ){
    *pzErr = sqlite3_mprintf("one argument requires: the name of a view");
    return SQLITE_ERROR;
  }
  zView = argv[3];
  zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zView);
  if( zSql==0 ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  sqlite3_free(zSql);
  if( rc ){
    *pzErr = sqlite3_mprintf("not a valid view: \"%w\"", zView);
    return SQLITE_NOMEM;
  }
  pSchema = sqlite3_str_new(db);
  if( pSchema==0 ){
    sqlite3_finalize(pStmt);
    return SQLITE_NOMEM;
  }
  sqlite3_str_appendall(pSchema, "CREATE TABLE x");
  cSep = '(';
  for(i=0; i<sqlite3_column_count(pStmt); i++){
    const char *zName = sqlite3_column_name(pStmt,i);
    char **azNew = sqlite3_realloc64(azCol, sizeof(azCol[0])*(i+1));
    if( azNew==0 ){
      rc = SQLITE_NOMEM;
      goto shardvtab_connect_error;
    }
    sqlite3_str_appendf(pSchema, "%c\"%w\"", cSep, zName);
    cSep = ',';
    azCol = azNew;
    azCol[nCol] = sqlite3_mprintf("%s", zName);
    if( azCol[nCol]==0 ){
      rc = SQLITE_NOMEM;
      goto shardvtab_connect_error;
    }
    nCol++;
  }
  sqlite3_str_appendall(pSchema, ")");
  sqlite3_finalize(pStmt);
  pStmt = 0;
  zSql = sqlite3_str_finish(pSchema);
  pSchema = 0;
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
    goto shardvtab_connect_error;
  }
  rc = sqlite3_declare_vtab(db, zSql);
  sqlite3_free(zSql);
  if( rc!=SQLITE_OK ){
    goto shardvtab_connect_error;
  }else{
    size_t n = strlen(zView) + 1;
    pNew = sqlite3_malloc64( sizeof(*pNew) + n );
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ){
      rc = SQLITE_NOMEM;
      goto shardvtab_connect_error;
    }
    memset(pNew, 0, sizeof(*pNew));
    pNew->db = db;
    pNew->zView = (char*)&pNew[1];
    memcpy(pNew->zView, zView, n);
    pNew->nCol = nCol;
    pNew->azCol = azCol;
  }
  return SQLITE_OK;

shardvtab_connect_error:
  sqlite3_finalize(pStmt);
  for(i=0; i<nCol; i++) sqlite3_free(azCol[i]);
  sqlite3_free(azCol);
  sqlite3_free(sqlite3_str_finish(pSchema));
  return rc;
}

/*
** This method is the destructor for shardvtab_vtab objects.
*/
static int shardvtabDisconnect(sqlite3_vtab *pVtab){
  int i;
  shardvtab_vtab *p = (shardvtab_vtab*)pVtab;
  for(i=0; i<p->nCol; i++) sqlite3_free(p->azCol[i]);
  sqlite3_free(p->azCol);
  sqlite3_free(p);
  return SQLITE_OK;
}

/*
** Constructor for a new shardvtab_cursor object.
*/
static int shardvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  shardvtab_cursor *pCur;
  pCur = sqlite3_malloc( sizeof(*pCur) );
  if( pCur==0 ) return SQLITE_NOMEM;
  memset(pCur, 0, sizeof(*pCur));
  *ppCursor = &pCur->base;
  return SQLITE_OK;
}

/*
** Destructor for a shardvtab_cursor.
*/
static int shardvtabClose(sqlite3_vtab_cursor *cur){
  shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
  sqlite3_finalize(pCur->pStmt);
  sqlite3_free(pCur);
  return SQLITE_OK;
}


/*
** Advance a shardvtab_cursor to its next row of output.
*/
static int shardvtabNext(sqlite3_vtab_cursor *cur){
  shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
  int rc;
  rc = pCur->rcLastStep = sqlite3_step(pCur->pStmt);
  if( rc==SQLITE_ROW || rc==SQLITE_DONE ) return SQLITE_OK;
  return rc;
}

/*
** Return values of columns for the row at which the shardvtab_cursor
** is currently pointing.
*/
static int shardvtabColumn(
  sqlite3_vtab_cursor *cur,   /* The cursor */
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
  int i                       /* Which column to return */
){
  shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
  sqlite3_result_value(ctx, sqlite3_column_value(pCur->pStmt, i));
  return SQLITE_OK;
}

/*
** Return the rowid for the current row.  In this implementation, the
** rowid is the same as the output value.
*/
static int shardvtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  *pRowid = 0;
  return SQLITE_OK;
}

/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int shardvtabEof(sqlite3_vtab_cursor *cur){
  shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
  return pCur->rcLastStep!=SQLITE_ROW;
}

/*
** This method is called to "rewind" the shardvtab_cursor object back
** to the first row of output.  This method is always called at least
** once prior to any call to shardvtabColumn() or shardvtabRowid() or 
** shardvtabEof().
*/
static int shardvtabFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  shardvtab_cursor *pCur = (shardvtab_cursor *)pVtabCursor;
  shardvtab_vtab *pTab = (shardvtab_vtab *)pVtabCursor->pVtab;
  int rc;
  sqlite3_finalize(pCur->pStmt);
  pCur->pStmt = 0;
  rc = sqlite3_prepare_v2(pTab->db, idxStr, -1, &pCur->pStmt, 0);
  if( rc==SQLITE_OK ){
    int i;
    for(i=0; i<argc; i++){
      sqlite3_bind_value(pCur->pStmt, i+1, argv[i]);
    }
  }else{
    sqlite3_finalize(pCur->pStmt);
    pCur->pStmt = 0;
  }
  pCur->rcLastStep = rc;
  return rc;
}

/*
** SQLite will invoke this method one or more times while planning a query
** that uses the virtual table.  This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
*/
static int shardvtabBestIndex(
  sqlite3_vtab *tab,
  sqlite3_index_info *p
){
  shardvtab_vtab *pTab = (shardvtab_vtab*)tab;
  int i;
  int n;
  sqlite3_stmt *pStmt;
  int rc;
  sqlite3_str *pSql;
  char *zSep = "WHERE";
  char *zSql;
  pSql = sqlite3_str_new(pTab->db);
  if( pSql==0 ) return SQLITE_NOMEM;
  sqlite3_str_appendf(pSql, "SELECT * FROM \"%w\"", pTab->zView);
  for(i=n=0; i<p->nConstraint; i++){
    const char *zOp;
    int iCol;
    if( p->aConstraint[i].usable==0 ) continue;
    iCol = p->aConstraint[i].iColumn;
    if( iCol<0 ) continue;
    zOp = 0;
    switch( p->aConstraint[i].op ){
      case SQLITE_INDEX_CONSTRAINT_EQ:     zOp = "==";     break;
      case SQLITE_INDEX_CONSTRAINT_GT:     zOp = ">";      break;
      case SQLITE_INDEX_CONSTRAINT_LE:     zOp = "<=";     break;
      case SQLITE_INDEX_CONSTRAINT_LT:     zOp = "<";      break;
      case SQLITE_INDEX_CONSTRAINT_GE:     zOp = ">=";     break;
      case SQLITE_INDEX_CONSTRAINT_MATCH:  zOp = "MATCH";  break;
      case SQLITE_INDEX_CONSTRAINT_LIKE:   zOp = "LIKE";   break;
      case SQLITE_INDEX_CONSTRAINT_GLOB:   zOp = "GLOB";   break;
      case SQLITE_INDEX_CONSTRAINT_REGEXP: zOp = "REGEXP"; break;
      case SQLITE_INDEX_CONSTRAINT_NE:     zOp = "<>";     break;
      case SQLITE_INDEX_CONSTRAINT_IS:     zOp = "IS";     break;
    }
    if( zOp ){
      n++;
      p->aConstraintUsage[i].argvIndex = n;
      sqlite3_str_appendf(pSql, " %s (\"%w\" %s ?%d)", 
                          zSep, pTab->azCol[iCol], zOp, n);
      zSep = "AND";
    }
  }
  zSql = sqlite3_str_finish(pSql);
  if( zSql==0 ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
  if( rc==SQLITE_OK ){
    int x = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_COST, 0);
    p->estimatedCost = pow(2.0, 0.1*x);
    p->estimatedRows =
            sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_ROWS, 0);
    p->idxStr = zSql;
    p->needToFreeIdxStr = 1;
  }else{
    sqlite3_free(zSql);
  }
  sqlite3_finalize(pStmt);
  return rc;
}

/*
** This following structure defines all the methods for the 
** virtual table.
*/
static sqlite3_module shardvtabModule = {
  /* iVersion    */ 0,
  /* xCreate     */ shardvtabConnect,
  /* xConnect    */ shardvtabConnect,
  /* xBestIndex  */ shardvtabBestIndex,
  /* xDisconnect */ shardvtabDisconnect,
  /* xDestroy    */ shardvtabDisconnect,
  /* xOpen       */ shardvtabOpen,
  /* xClose      */ shardvtabClose,
  /* xFilter     */ shardvtabFilter,
  /* xNext       */ shardvtabNext,
  /* xEof        */ shardvtabEof,
  /* xColumn     */ shardvtabColumn,
  /* xRowid      */ shardvtabRowid,
  /* xUpdate     */ 0,
  /* xBegin      */ 0,
  /* xSync       */ 0,
  /* xCommit     */ 0,
  /* xRollback   */ 0,
  /* xFindMethod */ 0,
  /* xRename     */ 0,
  /* xSavepoint  */ 0,
  /* xRelease    */ 0,
  /* xRollbackTo */ 0,
  /* xShadowName */ 0
};


#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_shardvtab_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  rc = sqlite3_create_module(db, "shardvtab", &shardvtabModule, 0);
  return rc;
}

Changes to src/shell.c.in.

1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786



1787
1788
1789
1790
1791
1792
1793
1794
    }
  }
}

/*
** Display and reset the EXPLAIN QUERY PLAN data
*/
static void eqp_render(ShellState *p){
  EQPGraphRow *pRow = p->sGraph.pRow;
  if( pRow ){
    if( pRow->zText[0]=='-' ){
      if( pRow->pNext==0 ){
        eqp_reset(p);
        return;
      }
      utf8_printf(p->out, "%s\n", pRow->zText+3);
      p->sGraph.pRow = pRow->pNext;
      sqlite3_free(pRow);
    }else{



      utf8_printf(p->out, "QUERY PLAN\n");
    }
    p->sGraph.zPrefix[0] = 0;
    eqp_render_level(p, 0);
    eqp_reset(p);
  }
}








|











>
>
>
|







1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
    }
  }
}

/*
** Display and reset the EXPLAIN QUERY PLAN data
*/
static void eqp_render(ShellState *p, sqlite3_stmt *pStmt){
  EQPGraphRow *pRow = p->sGraph.pRow;
  if( pRow ){
    if( pRow->zText[0]=='-' ){
      if( pRow->pNext==0 ){
        eqp_reset(p);
        return;
      }
      utf8_printf(p->out, "%s\n", pRow->zText+3);
      p->sGraph.pRow = pRow->pNext;
      sqlite3_free(pRow);
    }else{
      int iCost, nRow;
      iCost = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_COST, 0);
      nRow = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_ROWS, 0);
      utf8_printf(p->out, "QUERY PLAN (log est cost=%d rows=%d)\n", iCost, nRow);
    }
    p->sGraph.zPrefix[0] = 0;
    eqp_render_level(p, 0);
    eqp_reset(p);
  }
}

3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
        zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
        rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
        if( rc==SQLITE_OK ){
          while( sqlite3_step(pExplain)==SQLITE_ROW ){
            const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
            int iEqpId = sqlite3_column_int(pExplain, 0);
            int iParentId = sqlite3_column_int(pExplain, 1);
            if( zEQPLine[0]=='-' ) eqp_render(pArg);
            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
          }
          eqp_render(pArg);
        }
        sqlite3_finalize(pExplain);
        sqlite3_free(zEQP);
        if( pArg->autoEQP>=AUTOEQP_full ){
          /* Also do an EXPLAIN for ".eqp full" mode */
          zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
          rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);







|


|







3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
        zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
        rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
        if( rc==SQLITE_OK ){
          while( sqlite3_step(pExplain)==SQLITE_ROW ){
            const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
            int iEqpId = sqlite3_column_int(pExplain, 0);
            int iParentId = sqlite3_column_int(pExplain, 1);
            if( zEQPLine[0]=='-' ) eqp_render(pArg, pExplain);
            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
          }
          eqp_render(pArg, pExplain);
        }
        sqlite3_finalize(pExplain);
        sqlite3_free(zEQP);
        if( pArg->autoEQP>=AUTOEQP_full ){
          /* Also do an EXPLAIN for ".eqp full" mode */
          zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
          rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
          explain_data_prepare(pArg, pStmt);
        }
      }

      bind_prepared_stmt(pArg, pStmt);
      exec_prepared_stmt(pArg, pStmt);
      explain_data_delete(pArg);
      eqp_render(pArg);

      /* print usage stats if stats on */
      if( pArg && pArg->statsOn ){
        display_stats(db, pArg, 0);
      }

      /* print loop-counters if required */







|







3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
          explain_data_prepare(pArg, pStmt);
        }
      }

      bind_prepared_stmt(pArg, pStmt);
      exec_prepared_stmt(pArg, pStmt);
      explain_data_delete(pArg);
      eqp_render(pArg, pStmt);

      /* print usage stats if stats on */
      if( pArg && pArg->statsOn ){
        display_stats(db, pArg, 0);
      }

      /* print loop-counters if required */

Changes to src/sqlite.h.in.

7843
7844
7845
7846
7847
7848
7849









7850
7851
7852
7853
7854
7855
7856
7857
7858
7859


7860
7861
7862
7863
7864
7865
7866
** cycle.
**
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
** <dd>^This is the approximate number of bytes of heap memory
** used to store the prepared statement.  ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.









** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
#define SQLITE_STMTSTATUS_SORT              2
#define SQLITE_STMTSTATUS_AUTOINDEX         3
#define SQLITE_STMTSTATUS_VM_STEP           4
#define SQLITE_STMTSTATUS_REPREPARE         5
#define SQLITE_STMTSTATUS_RUN               6
#define SQLITE_STMTSTATUS_MEMUSED           99



/*
** CAPI3REF: Custom Page Cache Object
**
** The sqlite3_pcache type is opaque.  It is implemented by
** the pluggable module.  The SQLite core has no knowledge of
** its size or internal structure and never deals with the







>
>
>
>
>
>
>
>
>










>
>







7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
** cycle.
**
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
** <dd>^This is the approximate number of bytes of heap memory
** used to store the prepared statement.  ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
**
** [[SQLITE_STMTSTATUS_EST_ROWS]] <dt>SQLITE_STMTSTATUS_EST_ROWS</dt>
** <dd>^A return value of X indicates that the query planner estimated
** that the query will return pow(2,X/10.0) rows.
**
** [[SQLITE_STMTSTATUS_EST_COST]] <dt>SQLITE_STMTSTATUS_EST_COST</dt>
** <dd>^A return value of X indicates that the query planner estimated
** the relative cost of running this statement to completion is
** pow(2,X/10.0).
** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
#define SQLITE_STMTSTATUS_SORT              2
#define SQLITE_STMTSTATUS_AUTOINDEX         3
#define SQLITE_STMTSTATUS_VM_STEP           4
#define SQLITE_STMTSTATUS_REPREPARE         5
#define SQLITE_STMTSTATUS_RUN               6
#define SQLITE_STMTSTATUS_MEMUSED           99
#define SQLITE_STMTSTATUS_EST_ROWS          100
#define SQLITE_STMTSTATUS_EST_COST          101

/*
** CAPI3REF: Custom Page Cache Object
**
** The sqlite3_pcache type is opaque.  It is implemented by
** the pluggable module.  The SQLite core has no knowledge of
** its size or internal structure and never deals with the

Changes to src/vdbe.h.

260
261
262
263
264
265
266

267
268
269
270
271
272
273
void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
#endif
void sqlite3VdbeSwap(Vdbe*,Vdbe*);
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
void sqlite3VdbeSetVarmask(Vdbe*, int);

#ifndef SQLITE_OMIT_TRACE
  char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite3BlobCompare(const Mem*, const Mem*);

void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);







>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
#endif
void sqlite3VdbeSwap(Vdbe*,Vdbe*);
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
void sqlite3VdbeSetVarmask(Vdbe*, int);
void sqlite3VdbeUpdateCostEstimates(Parse*, LogEst, LogEst);
#ifndef SQLITE_OMIT_TRACE
  char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite3BlobCompare(const Mem*, const Mem*);

void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);

Changes to src/vdbeInt.h.

421
422
423
424
425
426
427


428
429
430
431
432
433
434
  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
  bft changeCntOn:1;      /* True to update the change-counter */
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */


  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
  u32 aCounter[7];        /* Counters used by sqlite3_stmt_status() */
  char *zSql;             /* Text of the SQL statement that generated this */
#ifdef SQLITE_ENABLE_NORMALIZE
  char *zNormSql;         /* Normalization of the associated SQL statement */
  DblquoteStr *pDblStr;   /* List of double-quoted string literals */







>
>







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
  bft changeCntOn:1;      /* True to update the change-counter */
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */
  LogEst nRowEst;         /* Query planner of estimated number of output rows */
  LogEst iCostEst;        /* Query planner cost estimate */
  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
  u32 aCounter[7];        /* Counters used by sqlite3_stmt_status() */
  char *zSql;             /* Text of the SQL statement that generated this */
#ifdef SQLITE_ENABLE_NORMALIZE
  char *zNormSql;         /* Normalization of the associated SQL statement */
  DblquoteStr *pDblStr;   /* List of double-quoted string literals */

Changes to src/vdbeapi.c.

1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679











1680
1681




1682
1683
1684
1685
1686
1687
1688
}

/*
** Return the value of a status counter for a prepared statement
*/
int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
  Vdbe *pVdbe = (Vdbe*)pStmt;
  u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !pStmt 
   || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
  ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  if( op==SQLITE_STMTSTATUS_MEMUSED ){
    sqlite3 *db = pVdbe->db;
    sqlite3_mutex_enter(db->mutex);
    v = 0;
    db->pnBytesFreed = (int*)&v;
    sqlite3VdbeClearObject(db, pVdbe);
    sqlite3DbFree(db, pVdbe);
    db->pnBytesFreed = 0;
    sqlite3_mutex_leave(db->mutex);
  }else{











    v = pVdbe->aCounter[op];
    if( resetFlag ) pVdbe->aCounter[op] = 0;




  }
  return (int)v;
}

/*
** Return the SQL associated with a prepared statement
*/







|
<
|
<
<



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







1654
1655
1656
1657
1658
1659
1660
1661

1662


1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
}

/*
** Return the value of a status counter for a prepared statement
*/
int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
  Vdbe *pVdbe = (Vdbe*)pStmt;
  u32 v = 0;

  if( !pStmt ){


    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
  switch( op ){
    case SQLITE_STMTSTATUS_MEMUSED: {
      sqlite3 *db = pVdbe->db;
      sqlite3_mutex_enter(db->mutex);
      v = 0;
      db->pnBytesFreed = (int*)&v;
      sqlite3VdbeClearObject(db, pVdbe);
      sqlite3DbFree(db, pVdbe);
      db->pnBytesFreed = 0;
      sqlite3_mutex_leave(db->mutex);
      break;
    }
    case SQLITE_STMTSTATUS_EST_ROWS: {
      v = pVdbe->nRowEst;
      break;
    }
    case SQLITE_STMTSTATUS_EST_COST: {
      v = pVdbe->iCostEst;
      break;
    }
    default: {
      if( op>=0 && op<ArraySize(pVdbe->aCounter) ){
        v = pVdbe->aCounter[op];
        if( resetFlag ) pVdbe->aCounter[op] = 0;
      }else{
        (void)SQLITE_MISUSE_BKPT;
      }
    }
  }
  return (int)v;
}

/*
** Return the SQL associated with a prepared statement
*/

Changes to src/vdbeaux.c.

4843
4844
4845
4846
4847
4848
4849














4850
4851
4852
4853
4854
4855
4856
  assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
  if( iVar>=32 ){
    v->expmask |= 0x80000000;
  }else{
    v->expmask |= ((u32)1 << (iVar-1));
  }
}















/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
**
** OP_PureFunc means that the function must be deterministic, and should
** throw an error if it is given inputs that would make it non-deterministic.







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







4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
  assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
  if( iVar>=32 ){
    v->expmask |= 0x80000000;
  }else{
    v->expmask |= ((u32)1 << (iVar-1));
  }
}

/*
** Update the estimated cost fields
*/
void sqlite3VdbeUpdateCostEstimates(Parse *pParse, LogEst iCost, LogEst nRow){
  Vdbe *v = pParse->pVdbe;
  if( v->iCostEst ){
    v->iCostEst = sqlite3LogEstAdd(v->iCostEst, iCost+pParse->nQueryLoop) + 1;
    if( nRow > v->nRowEst ) v->nRowEst = nRow;
  }else{
    v->nRowEst = nRow;
    v->iCostEst = iCost + 1;
  }
}

/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
**
** OP_PureFunc means that the function must be deterministic, and should
** throw an error if it is given inputs that would make it non-deterministic.

Changes to src/where.c.

4359
4360
4361
4362
4363
4364
4365

4366
4367
4368
4369
4370
4371
4372
        pWInfo->revMask = revMask;
      }
    }
  }


  pWInfo->nRowOut = pFrom->nRow;


  /* Free temporary memory and return success */
  sqlite3DbFreeNN(db, pSpace);
  return SQLITE_OK;
}

/*







>







4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
        pWInfo->revMask = revMask;
      }
    }
  }


  pWInfo->nRowOut = pFrom->nRow;
  pWInfo->iTotalCost = pFrom->rCost;

  /* Free temporary memory and return success */
  sqlite3DbFreeNN(db, pSpace);
  return SQLITE_OK;
}

/*
5141
5142
5143
5144
5145
5146
5147

5148
5149
5150
5151
5152
5153
5154
  WhereLevel *pLevel;
  WhereLoop *pLoop;
  SrcList *pTabList = pWInfo->pTabList;
  sqlite3 *db = pParse->db;

  /* Generate loop termination code.
  */

  VdbeModuleComment((v, "End WHERE-core"));
  for(i=pWInfo->nLevel-1; i>=0; i--){
    int addr;
    pLevel = &pWInfo->a[i];
    pLoop = pLevel->pWLoop;
    if( pLevel->op!=OP_Noop ){
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT







>







5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
  WhereLevel *pLevel;
  WhereLoop *pLoop;
  SrcList *pTabList = pWInfo->pTabList;
  sqlite3 *db = pParse->db;

  /* Generate loop termination code.
  */
  sqlite3VdbeUpdateCostEstimates(pParse, pWInfo->iTotalCost, pWInfo->nRowOut);
  VdbeModuleComment((v, "End WHERE-core"));
  for(i=pWInfo->nLevel-1; i>=0; i--){
    int addr;
    pLevel = &pWInfo->a[i];
    pLoop = pLevel->pWLoop;
    if( pLevel->op!=OP_Noop ){
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT

Changes to src/whereInt.h.

458
459
460
461
462
463
464

465
466
467
468
469
470
471
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values */
  u8 bOrderedInnerLoop;     /* True if only the inner-most loop is ordered */
  int iTop;                 /* The very beginning of the WHERE loop */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  LogEst nRowOut;           /* Estimated number of output rows */

  WhereClause sWC;          /* Decomposition of the WHERE clause */
  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/*
** Private interfaces - callable only by other where.c routines.







>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values */
  u8 bOrderedInnerLoop;     /* True if only the inner-most loop is ordered */
  int iTop;                 /* The very beginning of the WHERE loop */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  LogEst nRowOut;           /* Estimated number of output rows */
  LogEst iTotalCost;        /* Cost estimate for the whole plan */
  WhereClause sWC;          /* Decomposition of the WHERE clause */
  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/*
** Private interfaces - callable only by other where.c routines.