/ Check-in [b55c0f14]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge recent enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA3-256: b55c0f14c3250cdd0b38193d9f4c4ad3da977d280d7509d0c8db8552176b2e10
User & Date: drh 2017-05-11 18:49:57
Context
2017-05-22
19:24
Pull in all changes from the 3.19.0 release. check-in: bbd2d0e1 user: drh tags: apple-osx
2017-05-11
18:49
Merge recent enhancements from trunk. check-in: b55c0f14 user: drh tags: apple-osx
18:42
Enhance the json_extract() function to reuse parses of the same JSON when the function appears multiple times in the same query. check-in: 3ba9e7ab user: drh tags: trunk
2017-04-24
16:14
Bring in all the latest enhancements from trunk. check-in: 031feebc user: drh tags: apple-osx
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
    ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 
    ** varints, where nCol is the number of columns in the FTS3 table.
    ** The first varint is the number of documents currently stored in
    ** the table. The following nCol varints contain the total amount of
    ** data stored in all rows of each column of the table, from left
    ** to right.
    */
    int rc;
    Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
    sqlite3_stmt *pStmt;
    sqlite3_int64 nDoc = 0;
    sqlite3_int64 nByte = 0;
    const char *pEnd;
    const char *a;








<







4783
4784
4785
4786
4787
4788
4789

4790
4791
4792
4793
4794
4795
4796
    ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 
    ** varints, where nCol is the number of columns in the FTS3 table.
    ** The first varint is the number of documents currently stored in
    ** the table. The following nCol varints contain the total amount of
    ** data stored in all rows of each column of the table, from left
    ** to right.
    */

    Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
    sqlite3_stmt *pStmt;
    sqlite3_int64 nDoc = 0;
    sqlite3_int64 nByte = 0;
    const char *pEnd;
    const char *a;

Changes to ext/fts5/fts5_index.c.

4188
4189
4190
4191
4192
4193
4194

4195
4196
4197
4198
4199
4200
4201
....
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255


4256





4257
4258
4259

4260
4261
4262
4263
4264
4265
4266
  int nInput;                     /* Number of input segments */
  Fts5SegWriter writer;           /* Writer object */
  Fts5StructureSegment *pSeg;     /* Output segment */
  Fts5Buffer term;
  int bOldest;                    /* True if the output segment is the oldest */
  int eDetail = p->pConfig->eDetail;
  const int flags = FTS5INDEX_QUERY_NOOUTPUT;


  assert( iLvl<pStruct->nLevel );
  assert( pLvl->nMerge<=pLvl->nSeg );

  memset(&writer, 0, sizeof(Fts5SegWriter));
  memset(&term, 0, sizeof(Fts5Buffer));
  if( pLvl->nMerge ){
................................................................................
      fts5MultiIterNext(p, pIter, 0, 0)
  ){
    Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
    int nPos;                     /* position-list size field value */
    int nTerm;
    const u8 *pTerm;

    /* Check for key annihilation. */
    if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;

    pTerm = fts5MultiIterTerm(pIter, &nTerm);
    if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
      if( pnRem && writer.nLeafWritten>nRem ){
        break;
      }








      /* This is a new term. Append a term to the output segment. */
      fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
      fts5BufferSet(&p->rc, &term, nTerm, pTerm);

    }

    /* Append the rowid to the output */
    /* WRITEPOSLISTSIZE */
    fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter));

    if( eDetail==FTS5_DETAIL_NONE ){







>







 







<
<
<





>
>
|
>
>
>
>
>


<
>







4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
....
4242
4243
4244
4245
4246
4247
4248



4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263

4264
4265
4266
4267
4268
4269
4270
4271
  int nInput;                     /* Number of input segments */
  Fts5SegWriter writer;           /* Writer object */
  Fts5StructureSegment *pSeg;     /* Output segment */
  Fts5Buffer term;
  int bOldest;                    /* True if the output segment is the oldest */
  int eDetail = p->pConfig->eDetail;
  const int flags = FTS5INDEX_QUERY_NOOUTPUT;
  int bTermWritten = 0;           /* True if current term already output */

  assert( iLvl<pStruct->nLevel );
  assert( pLvl->nMerge<=pLvl->nSeg );

  memset(&writer, 0, sizeof(Fts5SegWriter));
  memset(&term, 0, sizeof(Fts5Buffer));
  if( pLvl->nMerge ){
................................................................................
      fts5MultiIterNext(p, pIter, 0, 0)
  ){
    Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
    int nPos;                     /* position-list size field value */
    int nTerm;
    const u8 *pTerm;




    pTerm = fts5MultiIterTerm(pIter, &nTerm);
    if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
      if( pnRem && writer.nLeafWritten>nRem ){
        break;
      }
      fts5BufferSet(&p->rc, &term, nTerm, pTerm);
      bTermWritten =0;
    }

    /* Check for key annihilation. */
    if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;

    if( p->rc==SQLITE_OK && bTermWritten==0 ){
      /* This is a new term. Append a term to the output segment. */
      fts5WriteAppendTerm(p, &writer, nTerm, pTerm);

      bTermWritten = 1;
    }

    /* Append the rowid to the output */
    /* WRITEPOSLISTSIZE */
    fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter));

    if( eDetail==FTS5_DETAIL_NONE ){

Changes to ext/fts5/fts5_test_tok.c.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
**   end:     Byte offset of the byte immediately following the end of the
**            token within the input string.
**   pos:     Token offset of token within input.
**
*/
#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5)

#include <fts5.h>
#include <string.h>
#include <assert.h>

typedef struct Fts5tokTable Fts5tokTable;
typedef struct Fts5tokCursor Fts5tokCursor;
typedef struct Fts5tokRow Fts5tokRow;








|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
**   end:     Byte offset of the byte immediately following the end of the
**            token within the input string.
**   pos:     Token offset of token within input.
**
*/
#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5)

#include "fts5.h"
#include <string.h>
#include <assert.h>

typedef struct Fts5tokTable Fts5tokTable;
typedef struct Fts5tokCursor Fts5tokCursor;
typedef struct Fts5tokRow Fts5tokRow;

Added ext/fts5/test/fts5delete.test.













































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 2017 May 12
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the FTS5 module.
#

source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5delete

# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}
fts5_aux_test_functions db

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<5000
  )
  INSERT INTO t1(rowid, x) SELECT i, (i/2)*2 FROM s;
}

do_test 1.1 {
  execsql BEGIN
  for {set i 1} {$i<=5000} {incr i} {
    if {$i % 2} {
      execsql { INSERT INTO t1 VALUES($i) }
    } else {
      execsql { DELETE FROM t1 WHERE rowid = $i }
    }
  }
  execsql COMMIT
} {}

do_test 1.2 {
  execsql { INSERT INTO t1(t1, rank) VALUES('usermerge', 2); }
  for {set i 0} {$i < 5} {incr i} {
    execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
    execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
  }
} {}

finish_test

Changes to ext/misc/json1.c.

167
168
169
170
171
172
173

174
175
176
177
178
179
180
...
408
409
410
411
412
413
414








415
416
417
418
419
420
421
...
959
960
961
962
963
964
965











































966
967
968
969
970
971
972
....
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337

1338
1339
1340
1341
1342
1343
1344
1345
1346


1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
....
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377

1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
....
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
  u32 nAlloc;        /* Number of slots of aNode[] allocated */
  JsonNode *aNode;   /* Array of nodes containing the parse */
  const char *zJson; /* Original JSON string */
  u32 *aUp;          /* Index of parent of each node */
  u8 oom;            /* Set to true if out of memory */
  u8 nErr;           /* Number of errors seen */
  u16 iDepth;        /* Nesting depth */

};

/*
** Maximum nesting depth of JSON for this implementation.
**
** This limit is needed to avoid a stack overflow in the recursive
** descent parser.  A depth of 2000 is far deeper than any sane JSON
................................................................................
  sqlite3_free(pParse->aNode);
  pParse->aNode = 0;
  pParse->nNode = 0;
  pParse->nAlloc = 0;
  sqlite3_free(pParse->aUp);
  pParse->aUp = 0;
}









/*
** Convert the JsonNode pNode into a pure JSON string and
** append to pOut.  Subsubstructure is also included.  Return
** the number of JsonNode objects that are encoded.
*/
static void jsonRenderNode(
................................................................................
  if( aUp==0 ){
    pParse->oom = 1;
    return SQLITE_NOMEM;
  }
  jsonParseFillInParentage(pParse, 0, 0);
  return SQLITE_OK;
}












































/*
** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
** a match.
*/
static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
  if( pNode->jnFlags & JNODE_RAW ){
................................................................................
** Return 0 if the input is not a well-formed JSON array.
*/
static void jsonArrayLengthFunc(
  sqlite3_context *ctx,
  int argc,
  sqlite3_value **argv
){
  JsonParse x;          /* The parse */
  sqlite3_int64 n = 0;
  u32 i;
  JsonNode *pNode;

  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;

  assert( x.nNode );
  if( argc==2 ){
    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
    pNode = jsonLookup(&x, zPath, 0, ctx);
  }else{
    pNode = x.aNode;
  }
  if( pNode==0 ){
    x.nErr = 1;


  }else if( pNode->eType==JSON_ARRAY ){
    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
    for(i=1; i<=pNode->n; n++){
      i += jsonNodeSize(&pNode[i]);
    }
  }
  if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
  jsonParseReset(&x);
}

/*
** json_extract(JSON, PATH, ...)
**
** Return the element described by PATH.  Return NULL if there is no
** PATH element.  If there are multiple PATHs, then return a JSON array
................................................................................
** is malformed.
*/
static void jsonExtractFunc(
  sqlite3_context *ctx,
  int argc,
  sqlite3_value **argv
){
  JsonParse x;          /* The parse */
  JsonNode *pNode;
  const char *zPath;
  JsonString jx;
  int i;

  if( argc<2 ) return;
  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;

  jsonInit(&jx, ctx);
  jsonAppendChar(&jx, '[');
  for(i=1; i<argc; i++){
    zPath = (const char*)sqlite3_value_text(argv[i]);
    pNode = jsonLookup(&x, zPath, 0, ctx);
    if( x.nErr ) break;
    if( argc>2 ){
      jsonAppendSeparator(&jx);
      if( pNode ){
        jsonRenderNode(pNode, &jx, 0);
      }else{
        jsonAppendRaw(&jx, "null", 4);
      }
................................................................................
  }
  if( argc>2 && i==argc ){
    jsonAppendChar(&jx, ']');
    jsonResult(&jx);
    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
  }
  jsonReset(&jx);
  jsonParseReset(&x);
}

/* This is the RFC 7396 MergePatch algorithm.
*/
static JsonNode *jsonMergePatch(
  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
  u32 iTarget,         /* Node of the TARGET in pParse */







>







 







>
>
>
>
>
>
>
>







 







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







 







|




|
>
|


|

|


<
>
>
|





|
<







 







|






|
>




|
|







 







<







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
...
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
....
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
....
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
....
1448
1449
1450
1451
1452
1453
1454

1455
1456
1457
1458
1459
1460
1461
  u32 nAlloc;        /* Number of slots of aNode[] allocated */
  JsonNode *aNode;   /* Array of nodes containing the parse */
  const char *zJson; /* Original JSON string */
  u32 *aUp;          /* Index of parent of each node */
  u8 oom;            /* Set to true if out of memory */
  u8 nErr;           /* Number of errors seen */
  u16 iDepth;        /* Nesting depth */
  int nJson;         /* Length of the zJson string in bytes */
};

/*
** Maximum nesting depth of JSON for this implementation.
**
** This limit is needed to avoid a stack overflow in the recursive
** descent parser.  A depth of 2000 is far deeper than any sane JSON
................................................................................
  sqlite3_free(pParse->aNode);
  pParse->aNode = 0;
  pParse->nNode = 0;
  pParse->nAlloc = 0;
  sqlite3_free(pParse->aUp);
  pParse->aUp = 0;
}

/*
** Free a JsonParse object that was obtained from sqlite3_malloc().
*/
static void jsonParseFree(JsonParse *pParse){
  jsonParseReset(pParse);
  sqlite3_free(pParse);
}

/*
** Convert the JsonNode pNode into a pure JSON string and
** append to pOut.  Subsubstructure is also included.  Return
** the number of JsonNode objects that are encoded.
*/
static void jsonRenderNode(
................................................................................
  if( aUp==0 ){
    pParse->oom = 1;
    return SQLITE_NOMEM;
  }
  jsonParseFillInParentage(pParse, 0, 0);
  return SQLITE_OK;
}

/*
** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
*/
#define JSON_CACHE_ID  (-429938)

/*
** Obtain a complete parse of the JSON found in the first argument
** of the argv array.  Use the sqlite3_get_auxdata() cache for this
** parse if it is available.  If the cache is not available or if it
** is no longer valid, parse the JSON again and return the new parse,
** and also register the new parse so that it will be available for
** future sqlite3_get_auxdata() calls.
*/
static JsonParse *jsonParseCached(
  sqlite3_context *pCtx,
  sqlite3_value **argv
){
  const char *zJson = (const char*)sqlite3_value_text(argv[0]);
  int nJson = sqlite3_value_bytes(argv[0]);
  JsonParse *p;
  if( zJson==0 ) return 0;
  p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
  if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
    p->nErr = 0;
    return p; /* The cached entry matches, so return it */
  }
  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
  if( p==0 ){
    sqlite3_result_error_nomem(pCtx);
    return 0;
  }
  memset(p, 0, sizeof(*p));
  p->zJson = (char*)&p[1];
  memcpy((char*)p->zJson, zJson, nJson+1);
  if( jsonParse(p, pCtx, p->zJson) ){
    sqlite3_free(p);
    return 0;
  }
  p->nJson = nJson;
  sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
  return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
}

/*
** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
** a match.
*/
static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
  if( pNode->jnFlags & JNODE_RAW ){
................................................................................
** Return 0 if the input is not a well-formed JSON array.
*/
static void jsonArrayLengthFunc(
  sqlite3_context *ctx,
  int argc,
  sqlite3_value **argv
){
  JsonParse *p;          /* The parse */
  sqlite3_int64 n = 0;
  u32 i;
  JsonNode *pNode;

  p = jsonParseCached(ctx, argv);
  if( p==0 ) return;
  assert( p->nNode );
  if( argc==2 ){
    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
    pNode = jsonLookup(p, zPath, 0, ctx);
  }else{
    pNode = p->aNode;
  }
  if( pNode==0 ){

    return;
  }
  if( pNode->eType==JSON_ARRAY ){
    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
    for(i=1; i<=pNode->n; n++){
      i += jsonNodeSize(&pNode[i]);
    }
  }
  sqlite3_result_int64(ctx, n);

}

/*
** json_extract(JSON, PATH, ...)
**
** Return the element described by PATH.  Return NULL if there is no
** PATH element.  If there are multiple PATHs, then return a JSON array
................................................................................
** is malformed.
*/
static void jsonExtractFunc(
  sqlite3_context *ctx,
  int argc,
  sqlite3_value **argv
){
  JsonParse *p;          /* The parse */
  JsonNode *pNode;
  const char *zPath;
  JsonString jx;
  int i;

  if( argc<2 ) return;
  p = jsonParseCached(ctx, argv);
  if( p==0 ) return;
  jsonInit(&jx, ctx);
  jsonAppendChar(&jx, '[');
  for(i=1; i<argc; i++){
    zPath = (const char*)sqlite3_value_text(argv[i]);
    pNode = jsonLookup(p, zPath, 0, ctx);
    if( p->nErr ) break;
    if( argc>2 ){
      jsonAppendSeparator(&jx);
      if( pNode ){
        jsonRenderNode(pNode, &jx, 0);
      }else{
        jsonAppendRaw(&jx, "null", 4);
      }
................................................................................
  }
  if( argc>2 && i==argc ){
    jsonAppendChar(&jx, ']');
    jsonResult(&jx);
    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
  }
  jsonReset(&jx);

}

/* This is the RFC 7396 MergePatch algorithm.
*/
static JsonNode *jsonMergePatch(
  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
  u32 iTarget,         /* Node of the TARGET in pParse */

Changes to ext/rtree/rtree.c.

3219
3220
3221
3222
3223
3224
3225

3226
3227
3228
3229
3230
3231
3232
**     INSERT INTO rtree...
**     DROP TABLE <tablename>;    -- Would fail with SQLITE_LOCKED
**   COMMIT;
*/
static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
  Rtree *pRtree = (Rtree *)pVtab;
  int iwt = pRtree->inWrTrans;

  pRtree->inWrTrans = 0;
  nodeBlobReset(pRtree);
  pRtree->inWrTrans = iwt;
  return SQLITE_OK;
}

/*







>







3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
**     INSERT INTO rtree...
**     DROP TABLE <tablename>;    -- Would fail with SQLITE_LOCKED
**   COMMIT;
*/
static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
  Rtree *pRtree = (Rtree *)pVtab;
  int iwt = pRtree->inWrTrans;
  UNUSED_PARAMETER(iSavepoint);
  pRtree->inWrTrans = 0;
  nodeBlobReset(pRtree);
  pRtree->inWrTrans = iwt;
  return SQLITE_OK;
}

/*

Changes to src/auth.c.

212
213
214
215
216
217
218












219
220
221
222
223
224
225
  if( db->init.busy || IN_DECLARE_VTAB ){
    return SQLITE_OK;
  }

  if( db->xAuth==0 ){
    return SQLITE_OK;
  }












  rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
                 ,db->auth.zAuthUser
#endif
                );
  if( rc==SQLITE_DENY ){
    sqlite3ErrorMsg(pParse, "not authorized");







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







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
  if( db->init.busy || IN_DECLARE_VTAB ){
    return SQLITE_OK;
  }

  if( db->xAuth==0 ){
    return SQLITE_OK;
  }

  /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
  ** callback are either NULL pointers or zero-terminated strings that
  ** contain additional details about the action to be authorized.
  **
  ** The following testcase() macros show that any of the 3rd through 6th
  ** parameters can be either NULL or a string. */
  testcase( zArg1==0 );
  testcase( zArg2==0 );
  testcase( zArg3==0 );
  testcase( pParse->zAuthContext==0 );

  rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
                 ,db->auth.zAuthUser
#endif
                );
  if( rc==SQLITE_DENY ){
    sqlite3ErrorMsg(pParse, "not authorized");

Changes to src/btree.c.

8192
8193
8194
8195
8196
8197
8198

8199
8200
8201
8202
8203
8204
8205
....
9316
9317
9318
9319
9320
9321
9322

9323
9324
9325
9326
9327
9328
9329
      return SQLITE_OK;
    }
    dropCell(pPage, idx, info.nSize, &rc);
    if( rc ) goto end_insert;
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
    idx = ++pCur->ix;

  }else{
    assert( pPage->leaf );
  }
  insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
  assert( pPage->nOverflow==0 || rc==SQLITE_OK );
  assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );

................................................................................

    /* Check for integer primary key out of range */
    if( pPage->intKey ){
      if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){
        checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
      }
      maxKey = info.nKey;

    }

    /* Check the content overflow list */
    if( info.nPayload>info.nLocal ){
      int nPage;       /* Number of pages on the overflow chain */
      Pgno pgnoOvfl;   /* First page of the overflow chain */
      assert( pc + info.nSize - 4 <= usableSize );







>







 







>







8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
....
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
      return SQLITE_OK;
    }
    dropCell(pPage, idx, info.nSize, &rc);
    if( rc ) goto end_insert;
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
    idx = ++pCur->ix;
    pCur->curFlags &= ~BTCF_ValidNKey;
  }else{
    assert( pPage->leaf );
  }
  insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
  assert( pPage->nOverflow==0 || rc==SQLITE_OK );
  assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );

................................................................................

    /* Check for integer primary key out of range */
    if( pPage->intKey ){
      if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){
        checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
      }
      maxKey = info.nKey;
      keyCanBeEqual = 0;     /* Only the first key on the page may ==maxKey */
    }

    /* Check the content overflow list */
    if( info.nPayload>info.nLocal ){
      int nPage;       /* Number of pages on the overflow chain */
      Pgno pgnoOvfl;   /* First page of the overflow chain */
      assert( pc + info.nSize - 4 <= usableSize );

Changes to src/delete.c.

346
347
348
349
350
351
352
353







354
355
356
357
358
359
360
    sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
  }

#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.
  ** It is easier just to erase the whole table. Prior to version 3.6.5,
  ** this optimization caused the row change count (the value returned by 
  ** API function sqlite3_count_changes) to be set incorrectly.  */







  if( rcauth==SQLITE_OK
   && pWhere==0
   && !bComplex
   && !IsVirtual(pTab)
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
   && db->xPreUpdateCallback==0
#endif







|
>
>
>
>
>
>
>







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
  }

#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.
  ** It is easier just to erase the whole table. Prior to version 3.6.5,
  ** this optimization caused the row change count (the value returned by 
  ** API function sqlite3_count_changes) to be set incorrectly.
  **
  ** The "rcauth==SQLITE_OK" terms is the
  ** IMPLEMENATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
  ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
  ** the truncate optimization is disabled and all rows are deleted
  ** individually.
  */
  if( rcauth==SQLITE_OK
   && pWhere==0
   && !bComplex
   && !IsVirtual(pTab)
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
   && db->xPreUpdateCallback==0
#endif

Changes to src/expr.c.

1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
....
1811
1812
1813
1814
1815
1816
1817



























































1818
1819
1820
1821
1822
1823
1824
    if( pList ){
      assert( pList->nExpr==iFirst+i+1 );
      pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
      pColumns->a[i].zName = 0;
    }
  }

  if( pExpr->op==TK_SELECT && pList ){
    Expr *pFirst = pList->a[iFirst].pExpr;
    assert( pFirst!=0 );
    assert( pFirst->op==TK_SELECT_COLUMN );
     
    /* Store the SELECT statement in pRight so it will be deleted when
    ** sqlite3ExprListDelete() is called */
    pFirst->pRight = pExpr;
................................................................................
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
*/
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
  return exprIsConst(p, 3, iCur);
}




























































/*
** Walk an expression tree.  Return non-zero if the expression is constant
** or a function call with constant arguments.  Return and 0 if there
** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is







|







 







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







1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
....
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
    if( pList ){
      assert( pList->nExpr==iFirst+i+1 );
      pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
      pColumns->a[i].zName = 0;
    }
  }

  if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
    Expr *pFirst = pList->a[iFirst].pExpr;
    assert( pFirst!=0 );
    assert( pFirst->op==TK_SELECT_COLUMN );
     
    /* Store the SELECT statement in pRight so it will be deleted when
    ** sqlite3ExprListDelete() is called */
    pFirst->pRight = pExpr;
................................................................................
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
*/
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
  return exprIsConst(p, 3, iCur);
}


/*
** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
*/
static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
  ExprList *pGroupBy = pWalker->u.pGroupBy;
  int i;

  /* Check if pExpr is identical to any GROUP BY term. If so, consider
  ** it constant.  */
  for(i=0; i<pGroupBy->nExpr; i++){
    Expr *p = pGroupBy->a[i].pExpr;
    if( sqlite3ExprCompare(pExpr, p, -1)<2 ){
      CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
      if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
        return WRC_Prune;
      }
    }
  }

  /* Check if pExpr is a sub-select. If so, consider it variable. */
  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    pWalker->eCode = 0;
    return WRC_Abort;
  }

  return exprNodeIsConstant(pWalker, pExpr);
}

/*
** Walk the expression tree passed as the first argument. Return non-zero
** if the expression consists entirely of constants or copies of terms 
** in pGroupBy that sort with the BINARY collation sequence.
**
** This routine is used to determine if a term of the HAVING clause can
** be promoted into the WHERE clause.  In order for such a promotion to work,
** the value of the HAVING clause term must be the same for all members of
** a "group".  The requirement that the GROUP BY term must be BINARY
** assumes that no other collating sequence will have a finer-grained
** grouping than binary.  In other words (A=B COLLATE binary) implies
** A=B in every other collating sequence.  The requirement that the
** GROUP BY be BINARY is stricter than necessary.  It would also work
** to promote HAVING clauses that use the same alternative collating
** sequence as the GROUP BY term, but that is much harder to check,
** alternative collating sequences are uncommon, and this is only an
** optimization, so we take the easy way out and simply require the
** GROUP BY to use the BINARY collating sequence.
*/
int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
  Walker w;
  memset(&w, 0, sizeof(w));
  w.eCode = 1;
  w.xExprCallback = exprNodeIsConstantOrGroupBy;
  w.u.pGroupBy = pGroupBy;
  w.pParse = pParse;
  sqlite3WalkExpr(&w, p);
  return w.eCode;
}

/*
** Walk an expression tree.  Return non-zero if the expression is constant
** or a function call with constant arguments.  Return and 0 if there
** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is

Changes to src/global.c.

133
134
135
136
137
138
139



140
141



142

143
144
145
146
147
148
149
**
** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.



*/
#ifndef SQLITE_USE_URI



# define  SQLITE_USE_URI 0

#endif

/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN







>
>
>


>
>
>
|
>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
**
** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
**
** URI filenames are enabled by default if SQLITE_HAS_CODEC is
** enabled.
*/
#ifndef SQLITE_USE_URI
# ifdef SQLITE_HAS_CODEC
#  define SQLITE_USE_URI 1
# else
#  define SQLITE_USE_URI 0
# endif
#endif

/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN

Changes to src/main.c.

3210
3211
3212
3213
3214
3215
3216

3217
3218
3219
3220
3221
3222
3223
3224
3225


3226
3227
3228
3229
3230
3231
3232
3233
    /* Opening a db handle. Fourth parameter is passed 0. */
    void *pArg = sqlite3GlobalConfig.pSqllogArg;
    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
  }
#endif
#if defined(SQLITE_HAS_CODEC)
  if( rc==SQLITE_OK ){

    const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
    if( zHexKey && zHexKey[0] ){
      u8 iByte;
      int i;
      char zKey[40];
      for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){
        iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]);
        if( (i&1)!=0 ) zKey[i/2] = iByte;
      }


      sqlite3_key_v2(db, 0, zKey, i/2);
    }
  }
#endif
  sqlite3_free(zOpen);
  return rc & 0xff;
}








>
|
<


|
|
|
|

>
>
|







3210
3211
3212
3213
3214
3215
3216
3217
3218

3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
    /* Opening a db handle. Fourth parameter is passed 0. */
    void *pArg = sqlite3GlobalConfig.pSqllogArg;
    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
  }
#endif
#if defined(SQLITE_HAS_CODEC)
  if( rc==SQLITE_OK ){
    const char *zKey;
    if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){;

      u8 iByte;
      int i;
      char zDecoded[40];
      for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
        iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
        if( (i&1)!=0 ) zDecoded[i/2] = iByte;
      }
      sqlite3_key_v2(db, 0, zDecoded, i/2);
    }else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){
      sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey));
    }
  }
#endif
  sqlite3_free(zOpen);
  return rc & 0xff;
}

Changes to src/pager.c.

2254
2255
2256
2257
2258
2259
2260





2261
2262
2263
2264
2265
2266
2267
....
2377
2378
2379
2380
2381
2382
2383










2384





2385
2386
2387
2388


2389
2390
2391



2392
2393
2394
2395
2396
2397
2398
....
2436
2437
2438
2439
2440
2441
2442

2443

2444
2445
2446
2447
2448
2449
2450
....
4460
4461
4462
4463
4464
4465
4466
4467


4468



4469
4470
4471
4472
4473
4474
4475
  int rc;
  PgHdr *pPg;                   /* An existing page in the cache */
  Pgno pgno;                    /* The page number of a page in journal */
  u32 cksum;                    /* Checksum used for sanity checking */
  char *aData;                  /* Temporary storage for the page */
  sqlite3_file *jfd;            /* The file descriptor for the journal file */
  int isSynced;                 /* True if journal page is synced */






  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */

  aData = pPager->pTmpSpace;
................................................................................
  if( isOpen(pPager->fd)
   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
   && isSynced
  ){
    i64 ofst = (pgno-1)*(i64)pPager->pageSize;
    testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
    assert( !pagerUseWal(pPager) );










    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);





    if( pgno>pPager->dbFileSize ){
      pPager->dbFileSize = pgno;
    }
    if( pPager->pBackup ){


      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);



    }
  }else if( !isMainJrnl && pPg==0 ){
    /* If this is a rollback of a savepoint and data was not written to
    ** the database and the page is not in-memory, there is a potential
    ** problem. When the page is next fetched by the b-tree layer, it 
    ** will be read from the database file, which may or may not be 
    ** current. 
................................................................................
    /* If this was page 1, then restore the value of Pager.dbFileVers.
    ** Do this before any decoding. */
    if( pgno==1 ){
      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
    }

    /* Decode the page just read from disk */

    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);

    sqlite3PcacheRelease(pPg);
  }
  return rc;
}

/*
** Parameter zMaster is the name of a master journal file. A single journal
................................................................................

    /* If the sub-journal was opened successfully (or was already open),
    ** write the journal record into the file.  */
    if( rc==SQLITE_OK ){
      void *pData = pPg->pData;
      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
      char *pData2;
  


      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);



      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
      }
    }
  }







>
>
>
>
>







 







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




>
>
|
|
|
>
>
>







 







>
|
>







 







|
>
>
|
>
>
>







2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
....
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
....
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
....
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
  int rc;
  PgHdr *pPg;                   /* An existing page in the cache */
  Pgno pgno;                    /* The page number of a page in journal */
  u32 cksum;                    /* Checksum used for sanity checking */
  char *aData;                  /* Temporary storage for the page */
  sqlite3_file *jfd;            /* The file descriptor for the journal file */
  int isSynced;                 /* True if journal page is synced */
#ifdef SQLITE_HAS_CODEC
  /* The jrnlEnc flag is true if Journal pages should be passed through
  ** the codec.  It is false for pure in-memory journals. */
  const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
#endif

  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */

  aData = pPager->pTmpSpace;
................................................................................
  if( isOpen(pPager->fd)
   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
   && isSynced
  ){
    i64 ofst = (pgno-1)*(i64)pPager->pageSize;
    testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
    assert( !pagerUseWal(pPager) );

    /* Write the data read from the journal back into the database file.
    ** This is usually safe even for an encrypted database - as the data
    ** was encrypted before it was written to the journal file. The exception
    ** is if the data was just read from an in-memory sub-journal. In that
    ** case it must be encrypted here before it is copied into the database
    ** file.  */
#ifdef SQLITE_HAS_CODEC
    if( !jrnlEnc ){
      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
      rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
    }else
#endif
    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);

    if( pgno>pPager->dbFileSize ){
      pPager->dbFileSize = pgno;
    }
    if( pPager->pBackup ){
#ifdef SQLITE_HAS_CODEC
      if( jrnlEnc ){
        CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
        sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
        CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
      }else
#endif
      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
    }
  }else if( !isMainJrnl && pPg==0 ){
    /* If this is a rollback of a savepoint and data was not written to
    ** the database and the page is not in-memory, there is a potential
    ** problem. When the page is next fetched by the b-tree layer, it 
    ** will be read from the database file, which may or may not be 
    ** current. 
................................................................................
    /* If this was page 1, then restore the value of Pager.dbFileVers.
    ** Do this before any decoding. */
    if( pgno==1 ){
      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
    }

    /* Decode the page just read from disk */
#if SQLITE_HAS_CODEC
    if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
#endif
    sqlite3PcacheRelease(pPg);
  }
  return rc;
}

/*
** Parameter zMaster is the name of a master journal file. A single journal
................................................................................

    /* If the sub-journal was opened successfully (or was already open),
    ** write the journal record into the file.  */
    if( rc==SQLITE_OK ){
      void *pData = pPg->pData;
      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
      char *pData2;

#if SQLITE_HAS_CODEC   
      if( !pPager->subjInMemory ){
        CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
      }else
#endif
      pData2 = pData;
      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
      }
    }
  }

Changes to src/select.c.

4874
4875
4876
4877
4878
4879
4880

































































































4881
4882
4883
4884
4885
4886
4887
....
5014
5015
5016
5017
5018
5019
5020


5021
5022
5023
5024
5025
5026
























5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037




5038
5039
5040
5041
5042
5043
5044
....
5105
5106
5107
5108
5109
5110
5111


5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124




5125
5126
5127

5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138

5139
5140
5141
5142
5143
5144
5145
....
5339
5340
5341
5342
5343
5344
5345





5346
5347
5348
5349
5350
5351
5352
        pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
    );
  }
}
#else
# define explainSimpleCount(a,b,c)
#endif


































































































/*
** Generate code for the SELECT statement given in the p argument.  
**
** The results are returned according to the SelectDest structure.
** See comments in sqliteInt.h for further information.
**
................................................................................
    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
    pParse->nSelectIndent--;
#endif
    return rc;
  }
#endif



  /* Generate code for all sub-queries in the FROM clause
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    struct SrcList_item *pItem = &pTabList->a[i];
    SelectDest dest;
























    Select *pSub = pItem->pSelect;
    if( pSub==0 ) continue;

    /* Sometimes the code for a subquery will be generated more than
    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
    ** for example.  In that case, do not regenerate the code to manifest
    ** a view or the co-routine to implement a view.  The first instance
    ** is sufficient, though the subroutine to manifest the view does need
    ** to be invoked again. */
    if( pItem->addrFillSub ){
      if( pItem->fg.viaCoroutine==0 ){




        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
      }
      continue;
    }

    /* Increment Parse.nHeight by the height of the largest expression
    ** tree referred to by this, the parent select. The child select
................................................................................
      ** the content of this subquery.  pItem->addrFillSub will point
      ** to the address of the generated subroutine.  pItem->regReturn
      ** is a register allocated to hold the subroutine return address
      */
      int topAddr;
      int onceAddr = 0;
      int retAddr;


      assert( pItem->addrFillSub==0 );
      pItem->regReturn = ++pParse->nMem;
      topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
      pItem->addrFillSub = topAddr+1;
      if( pItem->fg.isCorrelated==0 ){
        /* If the subquery is not correlated and if we are not inside of
        ** a trigger, then we only need to compute the value of the subquery
        ** once. */
        onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
        VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }else{
        VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }




      sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
      sqlite3Select(pParse, pSub, &dest);

      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
      retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
      VdbeComment((v, "end %s", pItem->pTab->zName));
      sqlite3VdbeChangeP1(v, topAddr, retAddr);
      sqlite3ClearTempRegCache(pParse);
    }
    if( db->mallocFailed ) goto select_end;
    pParse->nHeight -= sqlite3SelectExprHeight(p);
  }
#endif


  /* Various elements of the SELECT copied into local variables for
  ** convenience */
  pEList = p->pEList;
  pWhere = p->pWhere;
  pGroupBy = p->pGroupBy;
  pHaving = p->pHaving;
................................................................................
    sNC.pAggInfo = &sAggInfo;
    sAggInfo.mnReg = pParse->nMem+1;
    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
    sAggInfo.pGroupBy = pGroupBy;
    sqlite3ExprAnalyzeAggList(&sNC, pEList);
    sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
    if( pHaving ){





      sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
      sNC.ncFlags |= NC_InAggFunc;
      sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);







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







 







>
>
|

<



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










>
>
>
>







 







>
>













>
>
>
>
|
|
|
>









<

>







 







>
>
>
>
>







4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
....
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121

5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
....
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269

5270
5271
5272
5273
5274
5275
5276
5277
5278
....
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
        pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
    );
  }
}
#else
# define explainSimpleCount(a,b,c)
#endif

/*
** Context object for havingToWhereExprCb().
*/
struct HavingToWhereCtx {
  Expr **ppWhere;
  ExprList *pGroupBy;
};

/*
** sqlite3WalkExpr() callback used by havingToWhere().
**
** If the node passed to the callback is a TK_AND node, return 
** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
**
** Otherwise, return WRC_Prune. In this case, also check if the 
** sub-expression matches the criteria for being moved to the WHERE
** clause. If so, add it to the WHERE clause and replace the sub-expression
** within the HAVING expression with a constant "1".
*/
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
  if( pExpr->op!=TK_AND ){
    struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
      sqlite3 *db = pWalker->pParse->db;
      Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
      if( pNew ){
        Expr *pWhere = *(p->ppWhere);
        SWAP(Expr, *pNew, *pExpr);
        pNew = sqlite3ExprAnd(db, pWhere, pNew);
        *(p->ppWhere) = pNew;
      }
    }
    return WRC_Prune;
  }
  return WRC_Continue;
}

/*
** Transfer eligible terms from the HAVING clause of a query, which is
** processed after grouping, to the WHERE clause, which is processed before
** grouping. For example, the query:
**
**   SELECT * FROM <tables> WHERE a=? GROUP BY b HAVING b=? AND c=?
**
** can be rewritten as:
**
**   SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=?
**
** A term of the HAVING expression is eligible for transfer if it consists
** entirely of constants and expressions that are also GROUP BY terms that
** use the "BINARY" collation sequence.
*/
static void havingToWhere(
  Parse *pParse,
  ExprList *pGroupBy,
  Expr *pHaving, 
  Expr **ppWhere
){
  struct HavingToWhereCtx sCtx;
  Walker sWalker;

  sCtx.ppWhere = ppWhere;
  sCtx.pGroupBy = pGroupBy;

  memset(&sWalker, 0, sizeof(sWalker));
  sWalker.pParse = pParse;
  sWalker.xExprCallback = havingToWhereExprCb;
  sWalker.u.pHavingCtx = &sCtx;
  sqlite3WalkExpr(&sWalker, pHaving);
}

/*
** Check to see if the pThis entry of pTabList is a self-join of a prior view.
** If it is, then return the SrcList_item for the prior view.  If it is not,
** then return 0.
*/
static struct SrcList_item *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
  struct SrcList_item *pThis   /* Search for prior reference to this subquery */
){
  struct SrcList_item *pItem;
  for(pItem = pTabList->a; pItem<pThis; pItem++){
    if( pItem->pSelect==0 ) continue;
    if( pItem->fg.viaCoroutine ) continue;
    if( pItem->zName==0 ) continue;
    if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
    if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
    if( sqlite3ExprCompare(pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) ){
      /* The view was modified by some other optimization such as
      ** pushDownWhereTerms() */
      continue;
    }
    return pItem;
  }
  return 0;
}

/*
** Generate code for the SELECT statement given in the p argument.  
**
** The results are returned according to the SelectDest structure.
** See comments in sqliteInt.h for further information.
**
................................................................................
    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
    pParse->nSelectIndent--;
#endif
    return rc;
  }
#endif

  /* For each term in the FROM clause, do two things:
  ** (1) Authorized unreferenced tables
  ** (2) Generate code for all sub-queries
  */

  for(i=0; i<pTabList->nSrc; i++){
    struct SrcList_item *pItem = &pTabList->a[i];
    SelectDest dest;
    Select *pSub;

    /* Issue SQLITE_READ authorizations with a fake column name for any tables that
    ** are referenced but from which no values are extracted. Examples of where these
    ** kinds of null SQLITE_READ authorizations would occur:
    **
    **     SELECT count(*) FROM t1;   -- SQLITE_READ t1.""
    **     SELECT t1.* FROM t1, t2;   -- SQLITE_READ t2.""
    **
    ** The fake column name is an empty string.  It is possible for a table to
    ** have a column named by the empty string, in which case there is no way to
    ** distinguish between an unreferenced table and an actual reference to the
    ** "" column.  The original design was for the fake column name to be a NULL,
    ** which would be unambiguous.  But legacy authorization callbacks might
    ** assume the column name is non-NULL and segfault.  The use of an empty string
    ** for the fake column name seems safer.
    */
    if( pItem->colUsed==0 ){
      sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
    }

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    /* Generate code for all sub-queries in the FROM clause
    */
    pSub = pItem->pSelect;
    if( pSub==0 ) continue;

    /* Sometimes the code for a subquery will be generated more than
    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
    ** for example.  In that case, do not regenerate the code to manifest
    ** a view or the co-routine to implement a view.  The first instance
    ** is sufficient, though the subroutine to manifest the view does need
    ** to be invoked again. */
    if( pItem->addrFillSub ){
      if( pItem->fg.viaCoroutine==0 ){
        /* The subroutine that manifests the view might be a one-time routine,
        ** or it might need to be rerun on each iteration because it
        ** encodes a correlated subquery. */
        testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
      }
      continue;
    }

    /* Increment Parse.nHeight by the height of the largest expression
    ** tree referred to by this, the parent select. The child select
................................................................................
      ** the content of this subquery.  pItem->addrFillSub will point
      ** to the address of the generated subroutine.  pItem->regReturn
      ** is a register allocated to hold the subroutine return address
      */
      int topAddr;
      int onceAddr = 0;
      int retAddr;
      struct SrcList_item *pPrior;

      assert( pItem->addrFillSub==0 );
      pItem->regReturn = ++pParse->nMem;
      topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
      pItem->addrFillSub = topAddr+1;
      if( pItem->fg.isCorrelated==0 ){
        /* If the subquery is not correlated and if we are not inside of
        ** a trigger, then we only need to compute the value of the subquery
        ** once. */
        onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
        VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }else{
        VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }
      pPrior = isSelfJoinView(pTabList, pItem);
      if( pPrior ){
        sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
      }else{
        sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
        explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
        sqlite3Select(pParse, pSub, &dest);
      }
      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
      retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
      VdbeComment((v, "end %s", pItem->pTab->zName));
      sqlite3VdbeChangeP1(v, topAddr, retAddr);
      sqlite3ClearTempRegCache(pParse);
    }
    if( db->mallocFailed ) goto select_end;
    pParse->nHeight -= sqlite3SelectExprHeight(p);

#endif
  }

  /* Various elements of the SELECT copied into local variables for
  ** convenience */
  pEList = p->pEList;
  pWhere = p->pWhere;
  pGroupBy = p->pGroupBy;
  pHaving = p->pHaving;
................................................................................
    sNC.pAggInfo = &sAggInfo;
    sAggInfo.mnReg = pParse->nMem+1;
    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
    sAggInfo.pGroupBy = pGroupBy;
    sqlite3ExprAnalyzeAggList(&sNC, pEList);
    sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
    if( pHaving ){
      if( pGroupBy ){
        assert( pWhere==p->pWhere );
        havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
        pWhere = p->pWhere;
      }
      sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
      sNC.ncFlags |= NC_InAggFunc;
      sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);

Changes to src/shell.c.

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
...
739
740
741
742
743
744
745




746
747
748
749
750
751
752
** since with %*.*s the width is measured in bytes, not characters.
*/
static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
  int i;
  int n;
  int aw = w<0 ? -w : w;
  char zBuf[1000];
  if( aw>sizeof(zBuf)/3 ) aw = sizeof(zBuf)/3;
  for(i=n=0; zUtf[i]; i++){
    if( (zUtf[i]&0xc0)!=0x80 ){
      n++;
      if( n==aw ){
        do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
        break;
      }
................................................................................
    u64 s[25];                /* Keccak state. 5x5 lines of 64 bits each */
    unsigned char x[1600];    /* ... or 1600 bytes */
  } u;
  unsigned nRate;        /* Bytes of input accepted per Keccak iteration */
  unsigned nLoaded;      /* Input bytes loaded into u.x[] so far this cycle */
  unsigned ixMask;       /* Insert next input into u.x[nLoaded^ixMask]. */
};





/*
** A single step of the Keccak mixing function for a 1600-bit state
*/
static void KeccakF1600Step(SHA3Context *p){
  int i;
  u64 B0, B1, B2, B3, B4;







|







 







>
>
>
>







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
** since with %*.*s the width is measured in bytes, not characters.
*/
static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
  int i;
  int n;
  int aw = w<0 ? -w : w;
  char zBuf[1000];
  if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
  for(i=n=0; zUtf[i]; i++){
    if( (zUtf[i]&0xc0)!=0x80 ){
      n++;
      if( n==aw ){
        do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
        break;
      }
................................................................................
    u64 s[25];                /* Keccak state. 5x5 lines of 64 bits each */
    unsigned char x[1600];    /* ... or 1600 bytes */
  } u;
  unsigned nRate;        /* Bytes of input accepted per Keccak iteration */
  unsigned nLoaded;      /* Input bytes loaded into u.x[] so far this cycle */
  unsigned ixMask;       /* Insert next input into u.x[nLoaded^ixMask]. */
};

/* Allow the following routine to use the B0 variable, which is also
** a macro in the termios.h header file */
#undef B0

/*
** A single step of the Keccak mixing function for a 1600-bit state
*/
static void KeccakF1600Step(SHA3Context *p){
  int i;
  u64 B0, B1, B2, B3, B4;

Changes to src/sqlite.h.in.

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
....
2670
2671
2672
2673
2674
2675
2676

2677
2678
2679
2680
2681
2682
2683
....
2697
2698
2699
2700
2701
2702
2703
2704
2705


2706
2707
2708
2709
2710
2711
2712
2713




2714
2715
2716
2717
2718
2719
2720
....
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762

4763
4764
4765
4766
4767
4768
4769
4770
....
4786
4787
4788
4789
4790
4791
4792




4793
4794
4795
4796
4797
4798
4799
** anti-virus programs.  By default, the windows VFS will retry file read,
** file write, and file delete operations up to 10 times, with a delay
** of 25 milliseconds before the first retry and with the delay increasing
** by an additional 25 milliseconds with each subsequent retry.  This
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted.  The values are changed for all database connections
** within the same process.  The argument is a pointer to an array of two
** integers where the first integer i the new retry count and the second
** integer is the delay.  If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
** interrogated.  The zDbName parameter is ignored.
**
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
................................................................................
** method.
*/
void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3

**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
** points during the compilation process, as logic is being created
................................................................................
** authorizer will fail with an error message explaining that
** access is denied. 
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
** to the callback are zero-terminated strings that contain additional
** details about the action to be authorized.


**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
** [prepared statement] statement is constructed to substitute
** a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.




** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
**
** An authorizer is used when [sqlite3_prepare | preparing]
** SQL statements from an untrusted source, to ensure that the SQL statements
** do not try to access data they are not allowed to see, or that they do not
................................................................................
** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression can be stored as
** metadata associated with the pattern string.  
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If there is no metadata

** associated with the function argument, this sqlite3_get_auxdata() interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function.  ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** NULL if the metadata has been discarded.
................................................................................
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^




**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
void *sqlite3_get_auxdata(sqlite3_context*, int N);
void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));








|







 







>







 







|
|
>
>








>
>
>
>







 







|
|
|
>
|







 







>
>
>
>







854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
....
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
....
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
....
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
....
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
** anti-virus programs.  By default, the windows VFS will retry file read,
** file write, and file delete operations up to 10 times, with a delay
** of 25 milliseconds before the first retry and with the delay increasing
** by an additional 25 milliseconds with each subsequent retry.  This
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted.  The values are changed for all database connections
** within the same process.  The argument is a pointer to an array of two
** integers where the first integer is the new retry count and the second
** integer is the delay.  If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
** interrogated.  The zDbName parameter is ignored.
**
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
................................................................................
** method.
*/
void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
** points during the compilation process, as logic is being created
................................................................................
** authorizer will fail with an error message explaining that
** access is denied. 
**
** ^The first parameter to the authorizer callback is a copy of the third
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
** to the callback are either NULL pointers or zero-terminated strings
** that contain additional details about the action to be authorized.
** Applications must always be prepared to encounter a NULL pointer in any
** of the third through the sixth parameters of the authorization callback.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
** [prepared statement] statement is constructed to substitute
** a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
** ^When a table is referenced by a [SELECT] but no column values are
** extracted from that table (for example in a query like
** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
**
** An authorizer is used when [sqlite3_prepare | preparing]
** SQL statements from an untrusted source, to ensure that the SQL statements
** do not try to access data they are not allowed to see, or that they do not
................................................................................
** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression can be stored as
** metadata associated with the pattern string.  
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
** value to the application-defined function.  ^N is zero for the left-most
** function argument.  ^If there is no metadata
** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function.  ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** NULL if the metadata has been discarded.
................................................................................
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** The value of the N parameter to these interfaces should be non-negative.
** Future enhancements may make use of negative N values to define new
** kinds of function caching behavior.
**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
void *sqlite3_get_auxdata(sqlite3_context*, int N);
void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));

Changes to src/sqliteInt.h.

3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327


3328
3329
3330
3331
3332
3333
3334
....
3790
3791
3792
3793
3794
3795
3796

3797
3798
3799
3800
3801
3802
3803
  Parse *pParse;                            /* Parser context.  */
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
  int walkerDepth;                          /* Number of subqueries */
  u8 eCode;                                 /* A small processing code */
  union {                                   /* Extra data for callback */
    NameContext *pNC;                          /* Naming context */
    int n;                                     /* A counter */
    int iCur;                                  /* A cursor number */
    SrcList *pSrcList;                         /* FROM clause */
    struct SrcCount *pSrcCount;                /* Counting column references */
    struct CCurHint *pCCurHint;                /* Used by codeCursorHint() */
    int *aiCol;                                /* array of column indexes */
    struct IdxCover *pIdxCover;                /* Check for index coverage */
    struct IdxExprTrans *pIdxTrans;            /* Convert indexed expr to column */


  } u;
};

/* Forward declarations */
int sqlite3WalkExpr(Walker*, Expr*);
int sqlite3WalkExprList(Walker*, ExprList*);
int sqlite3WalkSelect(Walker*, Select*);
................................................................................
void sqlite3RollbackTransaction(Parse*);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);

int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);
#endif
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);







|
|
|
|
|
|
|
|
|
>
>







 







>







3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
....
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
  Parse *pParse;                            /* Parser context.  */
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
  int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
  void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
  int walkerDepth;                          /* Number of subqueries */
  u8 eCode;                                 /* A small processing code */
  union {                                   /* Extra data for callback */
    NameContext *pNC;                         /* Naming context */
    int n;                                    /* A counter */
    int iCur;                                 /* A cursor number */
    SrcList *pSrcList;                        /* FROM clause */
    struct SrcCount *pSrcCount;               /* Counting column references */
    struct CCurHint *pCCurHint;               /* Used by codeCursorHint() */
    int *aiCol;                               /* array of column indexes */
    struct IdxCover *pIdxCover;               /* Check for index coverage */
    struct IdxExprTrans *pIdxTrans;           /* Convert indexed expr to column */
    ExprList *pGroupBy;                       /* GROUP BY clause */
    struct HavingToWhereCtx *pHavingCtx;      /* HAVING to WHERE clause ctx */
  } u;
};

/* Forward declarations */
int sqlite3WalkExpr(Walker*, Expr*);
int sqlite3WalkExprList(Walker*, ExprList*);
int sqlite3WalkSelect(Walker*, Select*);
................................................................................
void sqlite3RollbackTransaction(Parse*);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);
#endif
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);

Changes to src/tclsqlite.c.

1029
1030
1031
1032
1033
1034
1035




1036
1037
1038



1039
1040
1041
1042
1043
1044
1045
  ,const char *zArg5
#endif
){
  const char *zCode;
  Tcl_DString str;
  int rc;
  const char *zReply;




  SqliteDb *pDb = (SqliteDb*)pArg;
  if( pDb->disableAuth ) return SQLITE_OK;




  switch( code ){
    case SQLITE_COPY              : zCode="SQLITE_COPY"; break;
    case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;
    case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;
    case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
    case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
    case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;







>
>
>
>



>
>
>







1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
  ,const char *zArg5
#endif
){
  const char *zCode;
  Tcl_DString str;
  int rc;
  const char *zReply;
  /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
  ** callback is a copy of the third parameter to the
  ** sqlite3_set_authorizer() interface.
  */
  SqliteDb *pDb = (SqliteDb*)pArg;
  if( pDb->disableAuth ) return SQLITE_OK;

  /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
  ** integer action code that specifies the particular action to be
  ** authorized. */
  switch( code ){
    case SQLITE_COPY              : zCode="SQLITE_COPY"; break;
    case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;
    case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;
    case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
    case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
    case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;

Changes to src/test1.c.

4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
....
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_interrupt(db);
  return TCL_OK;
}

static u8 *sqlite3_stack_baseline = 0;

/*
** Fill the stack with a known bitpattern.
*/
static void prepStack(void){
  int i;
  u32 bigBuf[65536];
  for(i=0; i<sizeof(bigBuf)/sizeof(bigBuf[0]); i++) bigBuf[i] = 0xdeadbeef;
  sqlite3_stack_baseline = (u8*)&bigBuf[65536];
}

/*
** Get the current stack depth.  Used for debugging only.
*/
u64 sqlite3StackDepth(void){
  u8 x;
  return (u64)(sqlite3_stack_baseline - &x);
}

/*
** Usage:  sqlite3_stack_used DB SQL
**
** Try to measure the amount of stack space used by a call to sqlite3_exec
*/
static int SQLITE_TCLAPI test_stack_used(
  void * clientData,
  Tcl_Interp *interp,
  int argc,
  char **argv
){
  sqlite3 *db;
  int i;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
        " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  prepStack();
  (void)sqlite3_exec(db, argv[2], 0, 0, 0);
  for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){}
  Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
  return TCL_OK;
}

/*
** Usage: sqlite_delete_function DB function-name
**
** Delete the user function 'function-name' from database handle DB. It
** is assumed that the user function was created as UTF8, any number of
** arguments (the way the TCL interface does it).
*/
................................................................................
     { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
     { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
     { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
     { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
     { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
     { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
     { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
     { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
     { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
     { "printf",                        (Tcl_CmdProc*)test_printf           },
     { "sqlite3IoTrace",              (Tcl_CmdProc*)test_io_trace         },
     { "clang_sanitize_address",        (Tcl_CmdProc*)clang_sanitize_address },
  };
  static struct {
     char *zName;







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







 







<







4963
4964
4965
4966
4967
4968
4969














































4970
4971
4972
4973
4974
4975
4976
....
7614
7615
7616
7617
7618
7619
7620

7621
7622
7623
7624
7625
7626
7627
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_interrupt(db);
  return TCL_OK;
}















































/*
** Usage: sqlite_delete_function DB function-name
**
** Delete the user function 'function-name' from database handle DB. It
** is assumed that the user function was created as UTF8, any number of
** arguments (the way the TCL interface does it).
*/
................................................................................
     { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
     { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
     { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
     { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
     { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
     { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
     { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },

     { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
     { "printf",                        (Tcl_CmdProc*)test_printf           },
     { "sqlite3IoTrace",              (Tcl_CmdProc*)test_io_trace         },
     { "clang_sanitize_address",        (Tcl_CmdProc*)clang_sanitize_address },
  };
  static struct {
     char *zName;

Changes to src/util.c.

709
710
711
712
713
714
715

716
717
718
719
720
721
722
      memcpy(pValue, &u, 4);
      return 1;
    }else{
      return 0;
    }
  }
#endif

  while( zNum[0]=='0' ) zNum++;
  for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
    v = v*10 + c;
  }

  /* The longest decimal representation of a 32 bit integer is 10 digits:
  **







>







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
      memcpy(pValue, &u, 4);
      return 1;
    }else{
      return 0;
    }
  }
#endif
  if( !sqlite3Isdigit(zNum[0]) ) return 0;
  while( zNum[0]=='0' ) zNum++;
  for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
    v = v*10 + c;
  }

  /* The longest decimal representation of a 32 bit integer is 10 digits:
  **

Changes to src/vdbe.c.

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
....
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
....
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
....
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
....
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
....
3536
3537
3538
3539
3540
3541
3542































3543
3544
3545
3546
3547
3548
3549
....
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
....
5765
5766
5767
5768
5769
5770
5771
5772

5773
5774
5775
5776
5777
5778
5779
5780
....
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: {             /* jump */
jump_to_p2_and_check_for_interrupt:
  pOp = &aOp[pOp->p2 - 1];

  /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
  ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
  ** completion.  Check to see if sqlite3_interrupt() has been called
  ** or if the progress callback needs to be invoked. 
  **
  ** This code uses unstructured "goto" statements and does not look clean.
  ** But that is not due to sloppy coding habits. The code is written this
  ** way for performance, to avoid having to run the interrupt and progress
  ** checks on every opcode.  This helps sqlite3_step() to run about 1.5%
................................................................................
arithmetic_result_is_null:
  sqlite3VdbeMemSetNull(pOut);
  break;
}

/* Opcode: CollSeq P1 * * P4
**
** P4 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** If P1 is not zero, then it is a register that a subsequent min() or
** max() aggregate will set to 1 if the current row is not the minimum or
** maximum.  The P1 register is initialized to 0 by this instruction.
................................................................................
#ifndef SQLITE_OMIT_CAST
/* Opcode: Cast P1 P2 * * *
** Synopsis: affinity(r[P1])
**
** Force the value in register P1 to be the type defined by P2.
** 
** <ul>
** <li value="97"> TEXT
** <li value="98"> BLOB
** <li value="99"> NUMERIC
** <li value="100"> INTEGER
** <li value="101"> REAL
** </ul>
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_Cast: {                  /* in1 */
  assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL );
  testcase( pOp->p2==SQLITE_AFF_TEXT );
................................................................................
}

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

  zAffinity = pOp->p4.z;
  assert( zAffinity!=0 );
................................................................................
/* Opcode: MakeRecord P1 P2 P3 P4 *
** Synopsis: r[P3]=mkrec(r[P1@P2])
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
** in an index.  The OP_Column opcode can decode the record later.
**
** P4 may be a string that is P2 characters long.  The nth character of the
** string indicates the column affinity that should be used for the nth
** field of the index key.
**
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.
**
** If P4 is NULL then all index fields have the affinity BLOB.
*/
................................................................................
  testcase( pOp->p2 & OPFLAG_SEEKEQ );
#endif
  sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
                               (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
  if( rc ) goto abort_due_to_error;
  break;
}
































/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
** the main database is read-only.  The ephemeral
................................................................................
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: RowSetAdd P1 P2 * * *
** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
**
** An assertion fails if P2 is not an integer.
*/
case OP_RowSetAdd: {       /* in1, in2 */
  pIn1 = &aMem[pOp->p1];
  pIn2 = &aMem[pOp->p2];
................................................................................
  sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
  break;
}

/* Opcode: RowSetRead P1 P2 P3 * *
** Synopsis: r[P3]=rowset(P1)
**
** Extract the smallest value from boolean index P1 and put that value into

** register P3.  Or, if boolean index P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: {       /* jump, in1, out3 */
  i64 val;

  pIn1 = &aMem[pOp->p1];
  if( (pIn1->flags & MEM_RowSet)==0 
................................................................................
**
** Register P3 is assumed to hold a 64-bit integer value. If register P1
** contains a RowSet object and that RowSet object contains
** the value held in P3, jump to register P2. Otherwise, insert the
** integer in P3 into the RowSet and continue on to the
** next opcode.
**
** The RowSet object is optimized for the case where successive sets
** of integers, where each set contains no duplicates. Each set
** of values is identified by a unique P4 value. The first set
** must have P4==0, the final set P4=-1.  P4 must be either -1 or
** non-negative.  For non-negative values of P4 only the lower 4
** bits are significant.
**
** This allows optimizations: (a) when P4==0 there is no need to test
** the rowset object for P3, as it is guaranteed not to contain it,
** (b) when P4==-1 there is no need to insert the value, as it will
** never be tested for, and (c) when a value that is part of set X is
** inserted, there is no need to search to see if the same value was
** previously inserted as part of set X (only if it was previously
** inserted as part of some other set).
*/
case OP_RowSetTest: {                     /* jump, in1, in3 */







|







 







|







 







|
|
|
|
|







 







|
|







 







|
|







 







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







 







|







 







|
>
|







 







|
|
|
|
|
<


|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
....
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
....
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
....
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
....
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
....
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
....
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
....
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
....
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840

5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: {             /* jump */
jump_to_p2_and_check_for_interrupt:
  pOp = &aOp[pOp->p2 - 1];

  /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
  ** OP_VNext, or OP_SorterNext) all jump here upon
  ** completion.  Check to see if sqlite3_interrupt() has been called
  ** or if the progress callback needs to be invoked. 
  **
  ** This code uses unstructured "goto" statements and does not look clean.
  ** But that is not due to sloppy coding habits. The code is written this
  ** way for performance, to avoid having to run the interrupt and progress
  ** checks on every opcode.  This helps sqlite3_step() to run about 1.5%
................................................................................
arithmetic_result_is_null:
  sqlite3VdbeMemSetNull(pOut);
  break;
}

/* Opcode: CollSeq P1 * * P4
**
** P4 is a pointer to a CollSeq object. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** If P1 is not zero, then it is a register that a subsequent min() or
** max() aggregate will set to 1 if the current row is not the minimum or
** maximum.  The P1 register is initialized to 0 by this instruction.
................................................................................
#ifndef SQLITE_OMIT_CAST
/* Opcode: Cast P1 P2 * * *
** Synopsis: affinity(r[P1])
**
** Force the value in register P1 to be the type defined by P2.
** 
** <ul>
** <li> P2=='A' &rarr; BLOB
** <li> P2=='B' &rarr; TEXT
** <li> P2=='C' &rarr; NUMERIC
** <li> P2=='D' &rarr; INTEGER
** <li> P2=='E' &rarr; REAL
** </ul>
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_Cast: {                  /* in1 */
  assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL );
  testcase( pOp->p2==SQLITE_AFF_TEXT );
................................................................................
}

/* Opcode: Affinity P1 P2 * P4 *
** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The N-th character of the
** string indicates the column affinity that should be used for the N-th
** memory cell in the range.
*/
case OP_Affinity: {
  const char *zAffinity;   /* The affinity to be applied */

  zAffinity = pOp->p4.z;
  assert( zAffinity!=0 );
................................................................................
/* Opcode: MakeRecord P1 P2 P3 P4 *
** Synopsis: r[P3]=mkrec(r[P1@P2])
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
** in an index.  The OP_Column opcode can decode the record later.
**
** P4 may be a string that is P2 characters long.  The N-th character of the
** string indicates the column affinity that should be used for the N-th
** field of the index key.
**
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.
**
** If P4 is NULL then all index fields have the affinity BLOB.
*/
................................................................................
  testcase( pOp->p2 & OPFLAG_SEEKEQ );
#endif
  sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
                               (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
  if( rc ) goto abort_due_to_error;
  break;
}

/* Opcode: OpenDup P1 P2 * * *
**
** Open a new cursor P1 that points to the same ephemeral table as
** cursor P2.  The P2 cursor must have been opened by a prior OP_OpenEphemeral
** opcode.  Only ephemeral cursors may be duplicated.
**
** Duplicate ephemeral cursors are used for self-joins of materialized views.
*/
case OP_OpenDup: {
  VdbeCursor *pOrig;    /* The original cursor to be duplicated */
  VdbeCursor *pCx;      /* The new cursor */

  pOrig = p->apCsr[pOp->p2];
  assert( pOrig->pBtx!=0 );  /* Only ephemeral cursors can be duplicated */

  pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->isEphemeral = 1;
  pCx->pKeyInfo = pOrig->pKeyInfo;
  pCx->isTable = pOrig->isTable;
  rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
                          pCx->pKeyInfo, pCx->uc.pCursor);
  /* The sqlite3BtreeCursor() routine can only fail for the first cursor
  ** opened for a database.  Since there is already an open cursor when this
  ** opcode is run, the sqlite3BtreeCursor() cannot fail */
  assert( rc==SQLITE_OK );
  break;
}


/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
** the main database is read-only.  The ephemeral
................................................................................
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: RowSetAdd P1 P2 * * *
** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a RowSet object
** held in register P1.
**
** An assertion fails if P2 is not an integer.
*/
case OP_RowSetAdd: {       /* in1, in2 */
  pIn1 = &aMem[pOp->p1];
  pIn2 = &aMem[pOp->p2];
................................................................................
  sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
  break;
}

/* Opcode: RowSetRead P1 P2 P3 * *
** Synopsis: r[P3]=rowset(P1)
**
** Extract the smallest value from the RowSet object in P1
** and put that value into register P3.
** Or, if RowSet object P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: {       /* jump, in1, out3 */
  i64 val;

  pIn1 = &aMem[pOp->p1];
  if( (pIn1->flags & MEM_RowSet)==0 
................................................................................
**
** Register P3 is assumed to hold a 64-bit integer value. If register P1
** contains a RowSet object and that RowSet object contains
** the value held in P3, jump to register P2. Otherwise, insert the
** integer in P3 into the RowSet and continue on to the
** next opcode.
**
** The RowSet object is optimized for the case where sets of integers
** are inserted in distinct phases, which each set contains no duplicates.
** Each set is identified by a unique P4 value. The first set
** must have P4==0, the final set must have P4==-1, and for all other sets
** must have P4>0.

**
** This allows optimizations: (a) when P4==0 there is no need to test
** the RowSet object for P3, as it is guaranteed not to contain it,
** (b) when P4==-1 there is no need to insert the value, as it will
** never be tested for, and (c) when a value that is part of set X is
** inserted, there is no need to search to see if the same value was
** previously inserted as part of set X (only if it was previously
** inserted as part of some other set).
*/
case OP_RowSetTest: {                     /* jump, in1, in3 */

Changes to src/vdbeInt.h.

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
** Each auxiliary data pointer stored by a user defined function 
** implementation calling sqlite3_set_auxdata() is stored in an instance
** of this structure. All such structures associated with a single VM
** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
** when the VM is halted (if not before).
*/
struct AuxData {
  int iOp;                        /* Instruction number of OP_Function opcode */
  int iArg;                       /* Index of function argument. */
  void *pAux;                     /* Aux data pointer */
  void (*xDelete)(void *);        /* Destructor for the aux data */
  AuxData *pNext;                 /* Next element in list */
};

/*
** The "context" argument for an installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**







|
|

|
|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
** Each auxiliary data pointer stored by a user defined function 
** implementation calling sqlite3_set_auxdata() is stored in an instance
** of this structure. All such structures associated with a single VM
** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
** when the VM is halted (if not before).
*/
struct AuxData {
  int iAuxOp;                     /* Instruction number of OP_Function opcode */
  int iAuxArg;                    /* Index of function argument. */
  void *pAux;                     /* Aux data pointer */
  void (*xDeleteAux)(void*);      /* Destructor for the aux data */
  AuxData *pNextAux;              /* Next element in list */
};

/*
** The "context" argument for an installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**

Changes to src/vdbeapi.c.

816
817
818
819
820
821
822






823
824
825
826
827
828
829
830
831
832
833
834

835
836
837

838
839
840
841
842
843






844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863


864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
    return (void*)p->pMem->z;
  }
}

/*
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.






*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  AuxData *pAuxData;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#if SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx->pVdbe==0 ) return 0;
#else
  assert( pCtx->pVdbe!=0 );
#endif
  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;

  }

  return (pAuxData ? pAuxData->pAux : 0);

}

/*
** Set the auxiliary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.






*/
void sqlite3_set_auxdata(
  sqlite3_context *pCtx, 
  int iArg, 
  void *pAux, 
  void (*xDelete)(void*)
){
  AuxData *pAuxData;
  Vdbe *pVdbe = pCtx->pVdbe;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  if( iArg<0 ) goto failed;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pVdbe==0 ) goto failed;
#else
  assert( pVdbe!=0 );
#endif

  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;


  }
  if( pAuxData==0 ){
    pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
    if( !pAuxData ) goto failed;
    pAuxData->iOp = pCtx->iOp;
    pAuxData->iArg = iArg;
    pAuxData->pNext = pVdbe->pAuxData;
    pVdbe->pAuxData = pAuxData;
    if( pCtx->fErrorOrAux==0 ){
      pCtx->isError = 0;
      pCtx->fErrorOrAux = 1;
    }
  }else if( pAuxData->xDelete ){
    pAuxData->xDelete(pAuxData->pAux);
  }

  pAuxData->pAux = pAux;
  pAuxData->xDelete = xDelete;
  return;

failed:
  if( xDelete ){
    xDelete(pAux);
  }
}







>
>
>
>
>
>










|
|
>
|
|
<
>






>
>
>
>
>
>











<






|
|
>
>




|
|
|





|
|



|







816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
    return (void*)p->pMem->z;
  }
}

/*
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
**
** The left-most argument is 0.
**
** Undocumented behavior:  If iArg is negative then access a cache of
** auxiliary data pointers that is available to all functions within a
** single prepared statement.  The iArg values must match.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  AuxData *pAuxData;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#if SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx->pVdbe==0 ) return 0;
#else
  assert( pCtx->pVdbe!=0 );
#endif
  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
    if(  pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
      return pAuxData->pAux;
    }
  }

  return 0;
}

/*
** Set the auxiliary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
**
** The left-most argument is 0.
**
** Undocumented behavior:  If iArg is negative then make the data available
** to all functions within the current prepared statement using iArg as an
** access code.
*/
void sqlite3_set_auxdata(
  sqlite3_context *pCtx, 
  int iArg, 
  void *pAux, 
  void (*xDelete)(void*)
){
  AuxData *pAuxData;
  Vdbe *pVdbe = pCtx->pVdbe;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pVdbe==0 ) goto failed;
#else
  assert( pVdbe!=0 );
#endif

  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
    if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
      break;
    }
  }
  if( pAuxData==0 ){
    pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
    if( !pAuxData ) goto failed;
    pAuxData->iAuxOp = pCtx->iOp;
    pAuxData->iAuxArg = iArg;
    pAuxData->pNextAux = pVdbe->pAuxData;
    pVdbe->pAuxData = pAuxData;
    if( pCtx->fErrorOrAux==0 ){
      pCtx->isError = 0;
      pCtx->fErrorOrAux = 1;
    }
  }else if( pAuxData->xDeleteAux ){
    pAuxData->xDeleteAux(pAuxData->pAux);
  }

  pAuxData->pAux = pAux;
  pAuxData->xDeleteAux = xDelete;
  return;

failed:
  if( xDelete ){
    xDelete(pAux);
  }
}

Changes to src/vdbeaux.c.

2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
....
2964
2965
2966
2967
2968
2969
2970


2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
  assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
  switch( pCx->eCurType ){
    case CURTYPE_SORTER: {
      sqlite3VdbeSorterClose(p->db, pCx);
      break;
    }
    case CURTYPE_BTREE: {
      if( pCx->pBtx ){
        sqlite3BtreeClose(pCx->pBtx);
        /* The pCx->pCursor will be close automatically, if it exists, by
        ** the call above. */
      }else{
        assert( pCx->uc.pCursor!=0 );
        sqlite3BtreeCloseCursor(pCx->uc.pCursor);
      }
      break;
................................................................................
**    * the corresponding bit in argument mask is clear (where the first
**      function parameter corresponds to bit 0 etc.).
*/
void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
  while( *pp ){
    AuxData *pAux = *pp;
    if( (iOp<0)


     || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
    ){
      testcase( pAux->iArg==31 );
      if( pAux->xDelete ){
        pAux->xDelete(pAux->pAux);
      }
      *pp = pAux->pNext;
      sqlite3DbFree(db, pAux);
    }else{
      pp= &pAux->pNext;
    }
  }
}

/*
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.







|
|







 







>
>
|

|
|
|

|


|







2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
....
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
  assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
  switch( pCx->eCurType ){
    case CURTYPE_SORTER: {
      sqlite3VdbeSorterClose(p->db, pCx);
      break;
    }
    case CURTYPE_BTREE: {
      if( pCx->isEphemeral ){
        if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx);
        /* The pCx->pCursor will be close automatically, if it exists, by
        ** the call above. */
      }else{
        assert( pCx->uc.pCursor!=0 );
        sqlite3BtreeCloseCursor(pCx->uc.pCursor);
      }
      break;
................................................................................
**    * the corresponding bit in argument mask is clear (where the first
**      function parameter corresponds to bit 0 etc.).
*/
void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
  while( *pp ){
    AuxData *pAux = *pp;
    if( (iOp<0)
     || (pAux->iAuxOp==iOp
          && pAux->iAuxArg>=0
          && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
    ){
      testcase( pAux->iAuxArg==31 );
      if( pAux->xDeleteAux ){
        pAux->xDeleteAux(pAux->pAux);
      }
      *pp = pAux->pNextAux;
      sqlite3DbFree(db, pAux);
    }else{
      pp= &pAux->pNextAux;
    }
  }
}

/*
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.

Changes to src/wherecode.c.

1125
1126
1127
1128
1129
1130
1131


1132
1133
1134
1135
1136
1137
1138
....
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
....
1701
1702
1703
1704
1705
1706
1707

1708
1709
1710
1711
1712
1713
1714
....
2018
2019
2020
2021
2022
2023
2024





2025


2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042




2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061


2062
2063
2064
2065
2066
2067
2068
  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrHalt;                   /* addrBrk for the outermost loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */



  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = &pWInfo->sWC;
  db = pParse->db;
  pLevel = &pWInfo->a[iLevel];
  pLoop = pLevel->pWLoop;
................................................................................
    int regBase;                 /* Base register holding constraint values */
    WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
    WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
    int startEq;                 /* True if range start uses ==, >= or <= */
    int endEq;                   /* True if range end uses ==, >= or <= */
    int start_constraints;       /* Start of range is constrained */
    int nConstraint;             /* Number of constraint terms */
    Index *pIdx;                 /* The index we will be using */
    int iIdxCur;                 /* The VDBE cursor for the index */
    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff = 0;           /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
................................................................................
    pLevel->p1 = iIdxCur;
    pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0;
    if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
    }else{
      assert( pLevel->p5==0 );
    }

  }else

#ifndef SQLITE_OMIT_OR_OPTIMIZATION
  if( pLoop->wsFlags & WHERE_MULTI_OR ){
    /* Case 5:  Two or more separately indexed terms connected by OR
    **
    ** Example:
................................................................................

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
#endif

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.





  */


  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    int skipLikeAddr = 0;
    testcase( pTerm->wtFlags & TERM_VIRTUAL );
    testcase( pTerm->wtFlags & TERM_CODED );
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
      testcase( pWInfo->untestedTerms==0
               && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
      pWInfo->untestedTerms = 1;
      continue;
    }
    pE = pTerm->pExpr;
    assert( pE!=0 );
    if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
      continue;
    }




    if( pTerm->wtFlags & TERM_LIKECOND ){
      /* If the TERM_LIKECOND flag is set, that means that the range search
      ** is sufficient to guarantee that the LIKE operator is true, so we
      ** can skip the call to the like(A,B) function.  But this only works
      ** for strings.  So do not skip the call to the function on the pass
      ** that compares BLOBs. */
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
      continue;
#else
      u32 x = pLevel->iLikeRepCntr;
      assert( x>0 );
      skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1));
      VdbeCoverage(v);
#endif
    }
    sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
    if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
    pTerm->wtFlags |= TERM_CODED;
  }



  /* Insert code to test for implied constraints based on transitivity
  ** of the "==" operator.
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code







>
>







 







<







 







>







 







>
>
>
>
>

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

|

|
|
|
|

|
|
|
|
|
>
>







1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
....
1452
1453
1454
1455
1456
1457
1458

1459
1460
1461
1462
1463
1464
1465
....
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
....
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrHalt;                   /* addrBrk for the outermost loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Index *pIdx = 0;          /* Index used by loop (if any) */
  int loopAgain;            /* True if constraint generator loop should repeat */

  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = &pWInfo->sWC;
  db = pParse->db;
  pLevel = &pWInfo->a[iLevel];
  pLoop = pLevel->pWLoop;
................................................................................
    int regBase;                 /* Base register holding constraint values */
    WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
    WhereTerm *pRangeEnd = 0;    /* Inequality constraint at range end */
    int startEq;                 /* True if range start uses ==, >= or <= */
    int endEq;                   /* True if range end uses ==, >= or <= */
    int start_constraints;       /* Start of range is constrained */
    int nConstraint;             /* Number of constraint terms */

    int iIdxCur;                 /* The VDBE cursor for the index */
    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff = 0;           /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
................................................................................
    pLevel->p1 = iIdxCur;
    pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0;
    if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
    }else{
      assert( pLevel->p5==0 );
    }
    if( omitTable ) pIdx = 0;
  }else

#ifndef SQLITE_OMIT_OR_OPTIMIZATION
  if( pLoop->wsFlags & WHERE_MULTI_OR ){
    /* Case 5:  Two or more separately indexed terms connected by OR
    **
    ** Example:
................................................................................

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
#endif

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.
  **
  ** This loop may run either once (pIdx==0) or twice (pIdx!=0). If
  ** it is run twice, then the first iteration codes those sub-expressions
  ** that can be computed using columns from pIdx only (without seeking
  ** the main table cursor). 
  */
  do{
    loopAgain = 0;
    for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
      Expr *pE;
      int skipLikeAddr = 0;
      testcase( pTerm->wtFlags & TERM_VIRTUAL );
      testcase( pTerm->wtFlags & TERM_CODED );
      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
      if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
        testcase( pWInfo->untestedTerms==0
            && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
        pWInfo->untestedTerms = 1;
        continue;
      }
      pE = pTerm->pExpr;
      assert( pE!=0 );
      if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
        continue;
      }
      if( pIdx && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
        loopAgain = 1;
        continue;
      }
      if( pTerm->wtFlags & TERM_LIKECOND ){
        /* If the TERM_LIKECOND flag is set, that means that the range search
        ** is sufficient to guarantee that the LIKE operator is true, so we
        ** can skip the call to the like(A,B) function.  But this only works
        ** for strings.  So do not skip the call to the function on the pass
        ** that compares BLOBs. */
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
        continue;
#else
        u32 x = pLevel->iLikeRepCntr;
        assert( x>0 );
        skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
        VdbeCoverage(v);
#endif
      }
      sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
      if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
      pTerm->wtFlags |= TERM_CODED;
    }
    pIdx = 0;
  }while( loopAgain );

  /* Insert code to test for implied constraints based on transitivity
  ** of the "==" operator.
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code

Changes to test/auth.test.

32
33
34
35
36
37
38

39
40
41
42
43
44







45
46
47
48
49
50
51
..
56
57
58
59
60
61
62



63
64
65
66
67
68
69
...
308
309
310
311
312
313
314




315
316
317
318
319
320
321
....
1602
1603
1604
1605
1606
1607
1608


1609
1610
1611
1612
1613
1614
1615
....
2474
2475
2476
2477
2478
2479
2480





























2481
2482
2483
2484
    db authorizer ::auth
  }
}

do_test auth-1.1.1 {
  db close
  set ::DB [sqlite3 db test.db]

  proc auth {code arg1 arg2 arg3 arg4 args} {
    if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} {
      return SQLITE_DENY
    }
    return SQLITE_OK
  }







  db authorizer ::auth
  catchsql {CREATE TABLE t1(a,b,c)}
} {1 {not authorized}}
do_test auth-1.1.2 {
  db errorcode
} {23}
do_test auth-1.1.3 {
................................................................................
  catchsql {
    SELECT x;
  }
} {1 {no such column: x}}
do_test auth-1.2 {
  execsql {SELECT name FROM sqlite_master}
} {}



do_test auth-1.3.1 {
  proc auth {code arg1 arg2 arg3 arg4 args} {
    if {$code=="SQLITE_CREATE_TABLE"} {
      set ::authargs [list $arg1 $arg2 $arg3 $arg4]
      return SQLITE_DENY
    }
    return SQLITE_OK
................................................................................
ifcapable attach {
  do_test auth-1.35.2 {
    execsql {ATTACH DATABASE 'test.db' AS two}
    catchsql {SELECT * FROM two.t2}
  } {1 {access to two.t2.b is prohibited}}
  execsql {DETACH DATABASE two}
}




do_test auth-1.36 {
  proc auth {code arg1 arg2 arg3 arg4 args} {
    if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} {
      return SQLITE_IGNORE
    }
    return SQLITE_OK
  }
................................................................................
do_test auth-1.247 {
  catchsql {END TRANSACTION}
} {1 {not authorized}}
do_test auth-1.248 {
  set ::authargs
} {COMMIT {} {} {}}
do_test auth-1.249 {


  db authorizer {}
  catchsql {ROLLBACK}
} {0 {}}
do_test auth-1.250 {
  execsql {SELECT * FROM t2}
} {11 2 33 7 8 9}

................................................................................
  set ::authargs
} [list                          \
  SQLITE_SELECT {} {} {} {}      \
  SQLITE_READ t7 a main {}       \
  SQLITE_READ t7 c main {}       \
]































rename proc {}
rename proc_real proc
finish_test







>






>
>
>
>
>
>
>







 







>
>
>







 







>
>
>
>







 







>
>







 







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




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
..
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
....
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
....
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
    db authorizer ::auth
  }
}

do_test auth-1.1.1 {
  db close
  set ::DB [sqlite3 db test.db]
  proc authx {code arg1 arg2 arg3 arg4 args} {return SQLITE_DENY}
  proc auth {code arg1 arg2 arg3 arg4 args} {
    if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} {
      return SQLITE_DENY
    }
    return SQLITE_OK
  }
  db authorizer ::authx
  # EVIDENCE-OF: R-03993-24285 Only a single authorizer can be in place on
  # a database connection at a time. Each call to sqlite3_set_authorizer
  # overrides the previous call.
  #
  # The authx authorizer above is overridden by the auth authorizer below
  # authx is never invoked.
  db authorizer ::auth
  catchsql {CREATE TABLE t1(a,b,c)}
} {1 {not authorized}}
do_test auth-1.1.2 {
  db errorcode
} {23}
do_test auth-1.1.3 {
................................................................................
  catchsql {
    SELECT x;
  }
} {1 {no such column: x}}
do_test auth-1.2 {
  execsql {SELECT name FROM sqlite_master}
} {}
# EVIDENCE-OF: R-04452-49349 When the callback returns SQLITE_DENY, the
# sqlite3_prepare_v2() or equivalent call that triggered the authorizer
# will fail with an error message explaining that access is denied.
do_test auth-1.3.1 {
  proc auth {code arg1 arg2 arg3 arg4 args} {
    if {$code=="SQLITE_CREATE_TABLE"} {
      set ::authargs [list $arg1 $arg2 $arg3 $arg4]
      return SQLITE_DENY
    }
    return SQLITE_OK
................................................................................
ifcapable attach {
  do_test auth-1.35.2 {
    execsql {ATTACH DATABASE 'test.db' AS two}
    catchsql {SELECT * FROM two.t2}
  } {1 {access to two.t2.b is prohibited}}
  execsql {DETACH DATABASE two}
}
# EVIDENCE-OF: R-38392-49970 If the action code is SQLITE_READ and the
# callback returns SQLITE_IGNORE then the prepared statement statement
# is constructed to substitute a NULL value in place of the table column
# that would have been read if SQLITE_OK had been returned.
do_test auth-1.36 {
  proc auth {code arg1 arg2 arg3 arg4 args} {
    if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} {
      return SQLITE_IGNORE
    }
    return SQLITE_OK
  }
................................................................................
do_test auth-1.247 {
  catchsql {END TRANSACTION}
} {1 {not authorized}}
do_test auth-1.248 {
  set ::authargs
} {COMMIT {} {} {}}
do_test auth-1.249 {
  # EVIDENCE-OF: R-52112-44167 Disable the authorizer by installing a NULL
  # callback.
  db authorizer {}
  catchsql {ROLLBACK}
} {0 {}}
do_test auth-1.250 {
  execsql {SELECT * FROM t2}
} {11 2 33 7 8 9}

................................................................................
  set ::authargs
} [list                          \
  SQLITE_SELECT {} {} {} {}      \
  SQLITE_READ t7 a main {}       \
  SQLITE_READ t7 c main {}       \
]

# If a table is referenced but no columns are read from the table,
# that causes a single SQLITE_READ authorization with a NULL column
# name.
#
# EVIDENCE-OF: R-31520-16302 When a table is referenced by a SELECT but
# no column values are extracted from that table (for example in a query
# like "SELECT count(*) FROM tab") then the SQLITE_READ authorizer
# callback is invoked once for that table with a column name that is an
# empty string.
#
set ::authargs [list]
do_test auth-8.1 {
  execsql {SELECT count(*) FROM t7}
  set ::authargs
} [list \
  SQLITE_SELECT {} {} {} {}          \
  SQLITE_FUNCTION {} count {} {}     \
  SQLITE_READ t7 {} {} {}            \
  ]
set ::authargs [list]

do_test auth-8.2 {
  execsql {SELECT t6.a FROM t6, t7}
  set ::authargs
} [list \
  SQLITE_SELECT {} {} {} {}          \
  SQLITE_READ t6 a main {}           \
  SQLITE_READ t7 {} {} {}            \
  ]

rename proc {}
rename proc_real proc
finish_test

Changes to test/auth3.test.

49
50
51
52
53
54
55




56
57
58
59
60
61
62
    INSERT INTO t1 VALUES(4, 5, 6);
  }
} {}
do_test auth3.1.2 {
  set ::authcode SQLITE_DENY
  catchsql { DELETE FROM t1 }
} {1 {not authorized}}




do_test auth3.1.3 {
  set ::authcode SQLITE_INVALID
  catchsql { DELETE FROM t1 }
} {1 {authorizer malfunction}}
do_test auth3.1.4 {
  execsql { SELECT * FROM t1 }
} {1 2 3 4 5 6}







>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    INSERT INTO t1 VALUES(4, 5, 6);
  }
} {}
do_test auth3.1.2 {
  set ::authcode SQLITE_DENY
  catchsql { DELETE FROM t1 }
} {1 {not authorized}}
# EVIDENCE-OF: R-64962-58611 If the authorizer callback returns any
# value other than SQLITE_IGNORE, SQLITE_OK, or SQLITE_DENY then the
# sqlite3_prepare_v2() or equivalent call that triggered the authorizer
# will fail with an error message.
do_test auth3.1.3 {
  set ::authcode SQLITE_INVALID
  catchsql { DELETE FROM t1 }
} {1 {authorizer malfunction}}
do_test auth3.1.4 {
  execsql { SELECT * FROM t1 }
} {1 2 3 4 5 6}

Added test/cachespill.test.



























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 2017 April 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix cachespill

ifcapable !pager_pragmas {
  finish_test
  return
}

#-------------------------------------------------------------------------
# Test that "PRAGMA cache_spill = 0" completely disables cache spilling.
#
do_execsql_test 1.1 {
  PRAGMA auto_vacuum = 0;
  PRAGMA page_size = 1024;
  PRAGMA cache_size = 100;
  CREATE TABLE t1(a);
}

do_test 1.2 {
  file size test.db
} {2048}

do_test 1.3 {
  execsql {
    BEGIN;
      WITH s(i) AS (
        SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<200
      ) INSERT INTO t1 SELECT randomblob(900) FROM s;
  }
  expr {[file size test.db] > 50000}
} {1}

do_test 1.4 {
  execsql ROLLBACK
  file size test.db
} {2048}

do_test 1.5 {
  execsql {
    PRAGMA cache_spill = 0;
    BEGIN;
      WITH s(i) AS (
        SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<200
      ) INSERT INTO t1 SELECT randomblob(900) FROM s;
  }
  file size test.db
} {2048}

do_test 1.5 {
  execsql {
    ROLLBACK;
    PRAGMA cache_spill = 1;
    BEGIN;
      WITH s(i) AS (
        SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<200
      ) INSERT INTO t1 SELECT randomblob(900) FROM s;
  }
  expr {[file size test.db] > 50000}
} {1}

do_execsql_test 1.6 { ROLLBACK }


finish_test

Changes to test/conflict3.test.

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
#
# This file focuses on making sure that combinations of REPLACE,
# IGNORE, and FAIL conflict resolution play well together.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl


ifcapable !conflict {
  finish_test
  return
}

do_execsql_test conflict-1.1 {
  CREATE TABLE t1(
    a INTEGER PRIMARY KEY ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-1.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-1.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-1.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Replete the tests above, but this time on a table non-INTEGER primary key.
#
do_execsql_test conflict-2.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a INT PRIMARY KEY ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-2.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-2.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-2.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Replete again on a WITHOUT ROWID table.
#
do_execsql_test conflict-3.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a INT PRIMARY KEY ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-3.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-3.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-3.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Arrange the table rows in a different order and repeat.
#
do_execsql_test conflict-4.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL,
    a INT PRIMARY KEY ON CONFLICT REPLACE
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-4.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-4.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-4.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Arrange the table rows in a different order and repeat.
#
do_execsql_test conflict-5.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    b UNIQUE ON CONFLICT IGNORE,
    a INT PRIMARY KEY ON CONFLICT REPLACE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-5.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-5.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-5.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Arrange the table rows in a different order and repeat.
#
do_execsql_test conflict-6.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    c UNIQUE ON CONFLICT FAIL,
    a INT PRIMARY KEY ON CONFLICT REPLACE,
    b UNIQUE ON CONFLICT IGNORE
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-6.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-6.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-6.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test conflict-7.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b INTEGER PRIMARY KEY ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-7.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-7.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-7.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test conflict-8.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b INT PRIMARY KEY ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-8.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-8.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-8.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test conflict-9.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b INT PRIMARY KEY ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-9.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-9.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-9.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test conflict-10.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c INTEGER PRIMARY KEY ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-10.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-10.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-10.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test conflict-11.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c PRIMARY KEY ON CONFLICT FAIL
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test conflict-11.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test conflict-11.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test conflict-11.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}















finish_test







>






|











|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|





|












|







|


|


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



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
#
# This file focuses on making sure that combinations of REPLACE,
# IGNORE, and FAIL conflict resolution play well together.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix conflict3

ifcapable !conflict {
  finish_test
  return
}

do_execsql_test 1.1 {
  CREATE TABLE t1(
    a INTEGER PRIMARY KEY ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 1.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 1.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 1.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Replete the tests above, but this time on a table non-INTEGER primary key.
#
do_execsql_test 2.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a INT PRIMARY KEY ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 2.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 2.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 2.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Replete again on a WITHOUT ROWID table.
#
do_execsql_test 3.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a INT PRIMARY KEY ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 3.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 3.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 3.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Arrange the table rows in a different order and repeat.
#
do_execsql_test 4.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    b UNIQUE ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL,
    a INT PRIMARY KEY ON CONFLICT REPLACE
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 4.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 4.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 4.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Arrange the table rows in a different order and repeat.
#
do_execsql_test 5.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    b UNIQUE ON CONFLICT IGNORE,
    a INT PRIMARY KEY ON CONFLICT REPLACE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 5.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 5.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 5.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Arrange the table rows in a different order and repeat.
#
do_execsql_test 6.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    c UNIQUE ON CONFLICT FAIL,
    a INT PRIMARY KEY ON CONFLICT REPLACE,
    b UNIQUE ON CONFLICT IGNORE
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 6.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 6.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 6.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test 7.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b INTEGER PRIMARY KEY ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 7.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 7.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 7.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test 8.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b INT PRIMARY KEY ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 8.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 8.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 8.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test 9.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b INT PRIMARY KEY ON CONFLICT IGNORE,
    c UNIQUE ON CONFLICT FAIL
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 9.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 9.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 9.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test 10.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c INTEGER PRIMARY KEY ON CONFLICT FAIL
  );
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 10.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 10.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 10.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Change which column is the PRIMARY KEY
#
do_execsql_test 11.1 {
  DROP TABLE t1;
  CREATE TABLE t1(
    a UNIQUE ON CONFLICT REPLACE, 
    b UNIQUE ON CONFLICT IGNORE,
    c PRIMARY KEY ON CONFLICT FAIL
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert a row that conflicts on column B.  The insert should be ignored.
#
do_execsql_test 11.2 {
  INSERT INTO t1(a,b,c) VALUES(3,2,5);
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4}

# Insert two rows where the second conflicts on C.  The first row show go
# and and then there should be a constraint error.
#
do_test 11.3 {
  catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
} {1 {UNIQUE constraint failed: t1.c}}
do_execsql_test 11.4 {
  SELECT a,b,c FROM t1 ORDER BY a;
} {1 2 3 2 3 4 4 5 6}

# Check that ticket [f68dc596c4] has been fixed.
#
do_execsql_test 12.1 {
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b TEXT);
  INSERT INTO t2 VALUES(111, '111');
}
do_execsql_test 12.2 {
  REPLACE INTO t2 VALUES(NULL, '112'), (111, '111B');
}
do_execsql_test 12.3 {
  SELECT * FROM t2;
} {111 111B 112 112}


finish_test

Changes to test/fkey5.test.

111
112
113
114
115
116
117
118
119



120
121
122
123
124
125
126
...
403
404
405
406
407
408
409



410
411
412
413
414
415
416
} {1 {no such table: temp.c2}}

# EVIDENCE-OF: R-45728-08709 There are four columns in each result row.
#
# EVIDENCE-OF: R-55672-01620 The first column is the name of the table
# that contains the REFERENCES clause.
#
# EVIDENCE-OF: R-25219-25618 The second column is the rowid of the row
# that contains the invalid REFERENCES clause.



#
# EVIDENCE-OF: R-40482-20265 The third column is the name of the table
# that is referred to.
#
# EVIDENCE-OF: R-62839-07969 The fourth column is the index of the
# specific foreign key constraint that failed.
#
................................................................................

  INSERT INTO p30 (id) VALUES (1);
  INSERT INTO c30 (master, line)  VALUES (1, 999);
}
do_execsql_test 10.2 {
  PRAGMA foreign_key_check;
}



do_execsql_test 10.3 {
  INSERT INTO c30 VALUES(45, 45);
  PRAGMA foreign_key_check;
} {c30 {} p30 0}

#-------------------------------------------------------------------------
# Test "foreign key mismatch" errors.







|
|
>
>
>







 







>
>
>







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
} {1 {no such table: temp.c2}}

# EVIDENCE-OF: R-45728-08709 There are four columns in each result row.
#
# EVIDENCE-OF: R-55672-01620 The first column is the name of the table
# that contains the REFERENCES clause.
#
# EVIDENCE-OF: R-00471-55166 The second column is the rowid of the row
# that contains the invalid REFERENCES clause, or NULL if the child
# table is a WITHOUT ROWID table.
#
# The second clause in the previous is tested by fkey5-10.3.
#
# EVIDENCE-OF: R-40482-20265 The third column is the name of the table
# that is referred to.
#
# EVIDENCE-OF: R-62839-07969 The fourth column is the index of the
# specific foreign key constraint that failed.
#
................................................................................

  INSERT INTO p30 (id) VALUES (1);
  INSERT INTO c30 (master, line)  VALUES (1, 999);
}
do_execsql_test 10.2 {
  PRAGMA foreign_key_check;
}
# EVIDENCE-OF: R-00471-55166 The second column is the rowid of the row
# that contains the invalid REFERENCES clause, or NULL if the child
# table is a WITHOUT ROWID table.
do_execsql_test 10.3 {
  INSERT INTO c30 VALUES(45, 45);
  PRAGMA foreign_key_check;
} {c30 {} p30 0}

#-------------------------------------------------------------------------
# Test "foreign key mismatch" errors.

Changes to test/fts3fault.test.

173
174
175
176
177
178
179

180
181
182
183
184
185
186

187
188
189
190
191
192
193
  execsql "INSERT INTO t8 VALUES('[string repeat {c } 50000]')"
  execsql "INSERT INTO t8 VALUES('d d d')"
  execsql "INSERT INTO t8 VALUES('e e e')"
  execsql "INSERT INTO t8(t8) VALUES('optimize')"
  faultsim_save_and_close
} {}


do_faultsim_test 8.1 -faults oom-t* -prep { 
  faultsim_restore_and_reopen
  db func mit mit
} -body {
  execsql { SELECT mit(matchinfo(t8, 'x')) FROM t8 WHERE t8 MATCH 'a b c' }
} -test {
  faultsim_test_result {0 {{1 1 1 1 4 2 1 5 5}}}

}

do_faultsim_test 8.2 -faults oom-t* -prep { 
  faultsim_restore_and_reopen
  db func mit mit
} -body {
  execsql { SELECT mit(matchinfo(t8, 's')) FROM t8 WHERE t8 MATCH 'a b c' }







>
|
|
|
|
|
|
|
>







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  execsql "INSERT INTO t8 VALUES('[string repeat {c } 50000]')"
  execsql "INSERT INTO t8 VALUES('d d d')"
  execsql "INSERT INTO t8 VALUES('e e e')"
  execsql "INSERT INTO t8(t8) VALUES('optimize')"
  faultsim_save_and_close
} {}

ifcapable fts4_deferred {
  do_faultsim_test 8.1 -faults oom-t* -prep { 
    faultsim_restore_and_reopen
    db func mit mit
  } -body {
    execsql { SELECT mit(matchinfo(t8, 'x')) FROM t8 WHERE t8 MATCH 'a b c' }
  } -test {
    faultsim_test_result {0 {{1 1 1 1 4 2 1 5 5}}}
  }
}

do_faultsim_test 8.2 -faults oom-t* -prep { 
  faultsim_restore_and_reopen
  db func mit mit
} -body {
  execsql { SELECT mit(matchinfo(t8, 's')) FROM t8 WHERE t8 MATCH 'a b c' }

Changes to test/fts3misc.test.

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
do_execsql_test 3.1.5 {
  SELECT rowid FROM t3 WHERE t3 MATCH '"2 3 4 5 6 7 8 9"'
} {4}

#-------------------------------------------------------------------------
#
reset_db

do_execsql_test 4.0 {
  PRAGMA page_size = 512;
  CREATE VIRTUAL TABLE t4 USING fts4;
  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<8000 )
  INSERT INTO t4 SELECT 'a b c a b c a b c' FROM s;
}
do_execsql_test 4.1 {
  SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
} {8000}
do_execsql_test 4.2 {
  SELECT quote(value) from t4_stat where id=0
} {X'C03EC0B204C0A608'}
do_execsql_test 4.3 {
  UPDATE t4_stat SET value = X'C03EC0B204C0A60800' WHERE id=0;
}
do_catchsql_test 4.4 {
  SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
} {1 {database disk image is malformed}}
do_execsql_test 4.5 {
  UPDATE t4_stat SET value = X'00C03EC0B204C0A608' WHERE id=0;
}
do_catchsql_test 4.6 {
  SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
} {1 {database disk image is malformed}}


#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE t5 USING fts4;
  INSERT INTO t5 VALUES('a x x x x b x x x x c');







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







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
do_execsql_test 3.1.5 {
  SELECT rowid FROM t3 WHERE t3 MATCH '"2 3 4 5 6 7 8 9"'
} {4}

#-------------------------------------------------------------------------
#
reset_db
ifcapable fts4_deferred {
  do_execsql_test 4.0 {
    PRAGMA page_size = 512;
    CREATE VIRTUAL TABLE t4 USING fts4;
    WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<8000 )
    INSERT INTO t4 SELECT 'a b c a b c a b c' FROM s;
  }
  do_execsql_test 4.1 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {8000}
  do_execsql_test 4.2 {
    SELECT quote(value) from t4_stat where id=0
  } {X'C03EC0B204C0A608'}
  do_execsql_test 4.3 {
    UPDATE t4_stat SET value = X'C03EC0B204C0A60800' WHERE id=0;
  }
  do_catchsql_test 4.4 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {1 {database disk image is malformed}}
  do_execsql_test 4.5 {
    UPDATE t4_stat SET value = X'00C03EC0B204C0A608' WHERE id=0;
  }
  do_catchsql_test 4.6 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {1 {database disk image is malformed}}
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE t5 USING fts4;
  INSERT INTO t5 VALUES('a x x x x b x x x x c');

Added test/having.test.





















































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 2017 April 30
#
# 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.
#
#***********************************************************************
#
# Test the HAVING->WHERE optimization.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix having

do_execsql_test 1.0 {
  CREATE TABLE t2(c, d);

  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 1);
  INSERT INTO t1 VALUES(2, 2);
  INSERT INTO t1 VALUES(1, 3);
  INSERT INTO t1 VALUES(2, 4);
  INSERT INTO t1 VALUES(1, 5);
  INSERT INTO t1 VALUES(2, 6);
} {}

foreach {tn sql res} {
  1 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING a=2" {2 12}
  2 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING a=2 AND sum(b)>10" {2 12}
  3 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING sum(b)>12" {}
} {
  do_execsql_test 1.$tn $sql $res
}

# Run an EXPLAIN command for both SQL statements. Return true if 
# the outputs are identical, or false otherwise.
#
proc compare_vdbe {sql1 sql2} {
  set r1 [list]
  set r2 [list]
  db eval "explain $sql1" { lappend r1 $opcode $p1 $p2 $p3 $p4 $p5}
  db eval "explain $sql2" { lappend r2 $opcode $p1 $p2 $p3 $p4 $p5}
  return [expr {$r1==$r2}]
}

proc do_compare_vdbe_test {tn sql1 sql2 res} {
  uplevel [list do_test $tn [list compare_vdbe $sql1 $sql2] $res]
}

#-------------------------------------------------------------------------
# Test that various statements that are eligible for the optimization
# produce the same VDBE code as optimizing by hand does.
#
foreach {tn sql1 sql2} {
  1 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a"

  2 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING sum(b)>5 AND a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a HAVING sum(b)>5"

  3 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a COLLATE binary"

  4 {
      SELECT x,y FROM (
        SELECT a AS x, sum(b) AS y FROM t1 
        GROUP BY a
      ) WHERE x BETWEEN 8888 AND 9999
    } {
      SELECT x,y FROM (
        SELECT a AS x, sum(b) AS y FROM t1 
        WHERE x BETWEEN 8888 AND 9999 
        GROUP BY a
      )
    }

  5 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING 0"
    "SELECT a, sum(b) FROM t1 WHERE 0 GROUP BY a COLLATE binary"

  6 "SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d HAVING b=d"
    "SELECT count(*) FROM t1,t2 WHERE a=c AND b=d GROUP BY b, d"

  7 {
      SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d 
      HAVING b=d COLLATE nocase
    } {
      SELECT count(*) FROM t1,t2 WHERE a=c AND b=d COLLATE nocase 
      GROUP BY b, d
    }

  8 "SELECT a, sum(b) FROM t1 GROUP BY a||b HAVING substr(a||b, 1, 1)='a'"
    "SELECT a, sum(b) FROM t1 WHERE substr(a||b, 1, 1)='a' GROUP BY a||b"
} {
  do_compare_vdbe_test 2.$tn $sql1 $sql2 1
}

#-------------------------------------------------------------------------
# 1: Test that the optimization is only applied if the GROUP BY term
#    uses BINARY collation.
#
# 2: Not applied if there is a non-deterministic function in the HAVING
#    term.
#
foreach {tn sql1 sql2} {
  1 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE nocase HAVING a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a COLLATE nocase"

  2 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING randomblob(a)<X'88'"
    "SELECT a, sum(b) FROM t1 WHERE randomblob(a)<X'88' GROUP BY a"
} {
  do_compare_vdbe_test 3.$tn $sql1 $sql2 0
}


#-------------------------------------------------------------------------
# Test that non-deterministic functions disqualify a term from being
# moved from the HAVING to WHERE clause.
#
do_execsql_test 4.1 {
  CREATE TABLE t3(a, b);
  INSERT INTO t3 VALUES(1, 1);
  INSERT INTO t3 VALUES(1, 2);
  INSERT INTO t3 VALUES(1, 3);
  INSERT INTO t3 VALUES(2, 1);
  INSERT INTO t3 VALUES(2, 2);
  INSERT INTO t3 VALUES(2, 3);
}

proc nondeter {args} {
  incr ::nondeter_ret
  expr {$::nondeter_ret % 2}
}
db func nondeter nondeter

set ::nondeter_ret 0
do_execsql_test 4.2 {
  SELECT a, sum(b) FROM t3 GROUP BY a HAVING nondeter(a)
} {1 6}

# If the term where moved, the query above would return the same
# result as the following. But it does not.
#
set ::nondeter_ret 0
do_execsql_test 4.3 {
  SELECT a, sum(b) FROM t3 WHERE nondeter(a) GROUP BY a
} {1 4 2 2}


finish_test

Added test/pushdown.test.























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 2017 April 29
#
# 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.
#
#***********************************************************************

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix pushdown

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(1, 'b1', 'c1');
  INSERT INTO t1 VALUES(2, 'b2', 'c2');
  INSERT INTO t1 VALUES(3, 'b3', 'c3');
  INSERT INTO t1 VALUES(4, 'b4', 'c4');
  CREATE INDEX i1 ON t1(a, c);
}

proc f {val} {
  lappend ::L $val
  return 0
}
db func f f 

do_test 1.1 {
  set L [list]
  execsql { SELECT * FROM t1 WHERE a=2 AND f(b) AND f(c) }
  set L
} {c2}

do_test 1.2 {
  set L [list]
  execsql { SELECT * FROM t1 WHERE a=3 AND f(c) AND f(b) }
  set L
} {c3}

do_execsql_test 1.3 {
  DROP INDEX i1;
  CREATE INDEX i1 ON t1(a, b);
}
do_test 1.4 {
  set L [list]
  execsql { SELECT * FROM t1 WHERE a=2 AND f(b) AND f(c) }
  set L
} {b2}

do_test 1.5 {
  set L [list]
  execsql { SELECT * FROM t1 WHERE a=3 AND f(c) AND f(b) }
  set L
} {b3}
  
finish_test

Added test/subjournal.test.













































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 2017 May 9
#
# 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix subjournal

do_execsql_test 1.0 {
  PRAGMA temp_store = memory;
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1 VALUES(1, 2, 3);
} {}
do_execsql_test 1.1 {
  BEGIN;
    INSERT INTO t1 VALUES(4, 5, 6);
    SAVEPOINT one;
      INSERT INTO t1 VALUES(7, 8, 9);
    ROLLBACK TO one;
    SELECT * FROM t1;
} {1 2 3 4 5 6}
do_execsql_test 1.2 {
  COMMIT;
}

do_execsql_test 2.0 {
  PRAGMA cache_size = 5;
  CREATE TABLE t2(a BLOB);
  CREATE INDEX i2 ON t2(a);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
  ) INSERT INTO t2 SELECT randomblob(500) FROM s;
}

do_test 2.1 {
  forcedelete test.db2
  sqlite3 db2 test2.db
  sqlite3_backup B db2 main db main
  set nPage [db one {PRAGMA page_count}]
  B step [expr $nPage-10]
} {SQLITE_OK}

do_execsql_test 2.2 {
  BEGIN;
    UPDATE t2 SET a=randomblob(499);
    SAVEPOINT two;
      UPDATE t2 SET a=randomblob(498);
    ROLLBACK TO two;
  COMMIT;
  PRAGMA integrity_check;
} {ok}

do_test 2.3 {
  B step 1000
} {SQLITE_DONE}
do_test 2.4 {
  B finish
  execsql { PRAGMA integrity_check } db2
} {ok}

finish_test

Changes to tool/lemon.c.

4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
  /* Mark rules that are actually used for reduce actions after all
  ** optimizations have been applied
  */
  for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE;
  for(i=0; i<lemp->nxstate; i++){
    for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
      if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){
        ap->x.rp->doesReduce = i;
      }
    }
  }

  /* Finish rendering the constants now that the action table has
  ** been computed */
  fprintf(out,"#define YYNSTATE             %d\n",lemp->nxstate);  lineno++;







|







4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
  /* Mark rules that are actually used for reduce actions after all
  ** optimizations have been applied
  */
  for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE;
  for(i=0; i<lemp->nxstate; i++){
    for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
      if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){
        ap->x.rp->doesReduce = 1;
      }
    }
  }

  /* Finish rendering the constants now that the action table has
  ** been computed */
  fprintf(out,"#define YYNSTATE             %d\n",lemp->nxstate);  lineno++;