/ Check-in [6153bcf4]
Login

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

Overview
Comment:Update this branch with latest trunk changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nulls-last
Files: files | file ages | folders
SHA3-256: 6153bcf41a9aa0497f8210311c99ac23846223068f2b6a3a1c2d9dec7673c7e1
User & Date: dan 2019-08-21 15:41:50
Context
2019-08-21
17:46
Disable broken test case in expert1.test. check-in: 73e30c2e user: dan tags: nulls-last
15:41
Update this branch with latest trunk changes. check-in: 6153bcf4 user: dan tags: nulls-last
14:54
Avoid assuming that "column IS ?", where column is declared UNIQUE, matches only a single row (as "?" might be NULL). Fix for [b8689402]. check-in: d02490a2 user: dan tags: trunk
2019-08-20
20:09
Further tests for the special null-handling on this branch. check-in: 0dbbb51f user: dan tags: nulls-last
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5







<







605
606
607
608
609
610
611

612
613
614
615
616
617
618
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE

FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5

Changes to Makefile.msc.

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF

# Should the session extension be enabled?  If so, add compilation options
# to enable it.







<







347
348
349
350
351
352
353

354
355
356
357
358
359
360
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1

OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF

# Should the session extension be enabled?  If so, add compilation options
# to enable it.

Changes to ext/fts3/fts3_snippet.c.

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
    SnippetPhrase *pPhrase = &pIter->aPhrase[i];
    if( pPhrase->pTail ){
      char *pCsr = pPhrase->pTail;
      int iCsr = pPhrase->iTail;

      while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
        int j;
        u64 mPhrase = (u64)1 << i;
        u64 mPos = (u64)1 << (iCsr - iStart);
        assert( iCsr>=iStart && (iCsr - iStart)<=64 );
        assert( i>=0 && i<=64 );
        if( (mCover|mCovered)&mPhrase ){
          iScore++;
        }else{
          iScore += 1000;
        }
        mCover |= mPhrase;








|


|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
    SnippetPhrase *pPhrase = &pIter->aPhrase[i];
    if( pPhrase->pTail ){
      char *pCsr = pPhrase->pTail;
      int iCsr = pPhrase->iTail;

      while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
        int j;
        u64 mPhrase = (u64)1 << (i%64);
        u64 mPos = (u64)1 << (iCsr - iStart);
        assert( iCsr>=iStart && (iCsr - iStart)<=64 );
        assert( i>=0 );
        if( (mCover|mCovered)&mPhrase ){
          iScore++;
        }else{
          iScore += 1000;
        }
        mCover |= mPhrase;

Changes to ext/fts5/fts5_main.c.

928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
  ** handles here, rather than preparing a new one for each query. But that
  ** is not possible as SQLite reference counts the virtual table objects.
  ** And since the statement required here reads from this very virtual 
  ** table, saving it creates a circular reference.
  **
  ** If SQLite a built-in statement cache, this wouldn't be a problem. */
  rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
      "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
      pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
      (zRankArgs ? ", " : ""),
      (zRankArgs ? zRankArgs : ""),
      bDesc ? "DESC" : "ASC"
  );

  pCsr->pSorter = pSorter;







|







928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
  ** handles here, rather than preparing a new one for each query. But that
  ** is not possible as SQLite reference counts the virtual table objects.
  ** And since the statement required here reads from this very virtual 
  ** table, saving it creates a circular reference.
  **
  ** If SQLite a built-in statement cache, this wouldn't be a problem. */
  rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
      "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
      pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
      (zRankArgs ? ", " : ""),
      (zRankArgs ? zRankArgs : ""),
      bDesc ? "DESC" : "ASC"
  );

  pCsr->pSorter = pSorter;

Changes to ext/fts5/test/fts5corrupt3.test.

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
...
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
....
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
....
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
....
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
....
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
....
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
....
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
....
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
....
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
....
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
....
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
....
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
....
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
....
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
....
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
....
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
....
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
....
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
....
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369

9370
9371
9372
9373
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c13.db
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
}]} {}

do_catchsql_test 13.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
} {1 {vtable constructor failed: t1}}

#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c14b.db
................................................................................
|     48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00   ................
|     64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00   p...........p...
| end c16.db
}]} {}

do_catchsql_test 15.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#---------------------------------------------------------------------------
#
reset_db
do_test 16.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
................................................................................
|    448: 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53   TUAL TABLE t1 US
|    464: 49 4e 47 20 66 74 73 35 28 61 2c 62 2c 63 29 00   ING fts5(a,b,c).
|    480: 00 00 39 00 00 00 00 00 00 00 00 00 00 00 00 00   ..9.............
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-fed6e90021ba5d.db
}]} {}

do_execsql_test 33.1 {
  CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
  CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
  CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance');
}

do_catchsql_test 33.2 {
  SELECT * FROM t2;
} {1 {database disk image is malformed}}

do_catchsql_test 33.3 {
  SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 34.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename crash-a60a9da4c8932f.db
................................................................................
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end null-memcmp-param-1..db
}]} {}

do_catchsql_test 37.1 {
  SELECT * FROM t3;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 37.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(b, c);
  INSERT INTO t1 VALUES('a', 'b');
  SELECT quote(block) FROM t1_data WHERE rowid=10;
} {X'000000000101010001010101'}

do_execsql_test 37.1 {
  UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
  SELECT rowid FROM t1('a');
} {1}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 38.0 {
................................................................................
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end crash-fd2a1313e5b5e9.db
}]} {}

do_catchsql_test 38.1 {
  UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*';
} {0 {}}

#-------------------------------------------------------------------------
reset_db
do_test 39.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
................................................................................
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
| end crash2.txt.db
}]} {}

do_execsql_test 40.1 {
  BEGIN;
  INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf');
  INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033');
  INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7');
}

do_catchsql_test 40.2 {
  INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44);
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
  REPLACE INTO t1_data VALUES(1,X'255a5824');
  REPLACE INTO t1_data VALUES(10,X'0a1000000102020002010101020101');
................................................................................
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
| end 89028ffd2c29b679e250.db
}]} {}

do_catchsql_test 43.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 44.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(a,b unindexed,c,tokenize="porter ascii");
  REPLACE INTO t1_data VALUES(1,X'03090009');
  REPLACE INTO t1_data VALUES(10,X'000000000103030003010101020101030101');
................................................................................
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
} {0 {}}

#--------------------------------------------------------------------------
reset_db
do_test 46.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-1ee8bd451dd1ad.db
................................................................................
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end crash-1ee8bd451dd1ad.db
}]} {}

do_catchsql_test 46.1 {
  SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*');
} {0 {{}}}

#--------------------------------------------------------------------------
reset_db
do_test 47.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename 4b6fc659283f2735616c.db
................................................................................
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end 4b6fc659283f2735616c.db
}]} {}

do_catchsql_test 47.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

do_catchsql_test 47.2 {
  SELECT count(*) FROM (
      SELECT snippet(t1, -1, '.', '..', '[', 50), 
      highlight(t1, 2, '[', ']') FROM t1('g h') 
      WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank
  )
} {0 3}

#--------------------------------------------------------------------------
reset_db
do_test 48.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-44a8305b4bd86f.db
................................................................................
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-2b92f77ddfe191.db
}]} {}

do_catchsql_test 52.1 {
  SELECT fts5_decode(id, block) FROM t1_data;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 53.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-dbe9b7614da103.db
................................................................................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 0c e9   ................
| end crash-dbe9b7614da103.db
}]} {}

do_catchsql_test 53.1 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 54.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-03a1855566d9ae.db
................................................................................
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 23 03 02 01 03 03 02 02 01 02 02 00 f2 09   ..#.............
| end crash-03a1855566d9ae.db
}]} {}

do_catchsql_test 54.1 {
  SELECT rowid==-1 FROM t1('t*');
} {0 {0 0 0}}

#-------------------------------------------------------------------------
reset_db
do_test 55.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-b366b5ac0d3887.db
................................................................................
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 77 72   .........+intewr
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end crash-b366b5ac0d3887.db
}]} {}

do_execsql_test 55.1 {
  SAVEPOINT one;
  DELETE FROM t1 WHERE a MATCH 'ts';
}

do_execsql_test 55.2 {
  ROLLBACK TO one;
}

#-------------------------------------------------------------------------
reset_db
................................................................................
  # may return SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. This is because
  # the corrupt db in the test over-reads the page buffer slightly, with
  # different results depending on whether or not the page-cache is in use.
  if {$res=="1 {constraint failed}"} {
    set res "1 {database disk image is malformed}"
  }
  set res
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 57.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename x.db
................................................................................
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end x.db
}]} {}

do_catchsql_test 57.1 {
  INSERT INTO t1(t1) VALUES('optimize')
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 58.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
................................................................................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|   4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00   ..#.............
| end crash-5a5acd0ab42d31.db
}]} {}

do_execsql_test 58.1 {
  SELECT * FROM t1('t*');
} {{} {} {} {} {} {}}

#-------------------------------------------------------------------------
do_test 59.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-96b136358d01ec.db
................................................................................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01   ................
| page 7 offset 24576
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-e5fa281edabddf.db
}]} {}

do_execsql_test 61.1 {
  CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' );
} 

do_catchsql_test 61.2 {
  SELECT * FROM t3 ORDER BY rowid;
} {1 {database disk image is malformed}}

breakpoint
#-------------------------------------------------------------------------
do_test 62.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
................................................................................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-44942694542e1e.db
}]} {}

do_catchsql_test 62.1 {
  WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {0 {}}

#---------------------------------------------------------------------------
do_test 63.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-8230e6c3b368f5.db
................................................................................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 08 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| end crash-8230e6c3b368f5.db
}]} {}

do_catchsql_test 63.1 {
  SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
} {1 {database disk image is malformed}}

do_catchsql_test 63.2 {
  INSERT INTO t1(t1) VALUES('optimize');
} {0 {}}

breakpoint
do_catchsql_test 63.3 {
  SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
} {0 {}}


sqlite3_fts5_may_be_corrupt 0
finish_test








|







 







|







 







|



|



|



|







 







|



|





|







 







|







 







|




|



|







 







|







 







|







 







|







 







|







|







 







|







 







|







 







|







 







|


|







 







|







 







|







 







|

|







 







|

|



|







 







|







 







|



|

<


<
>




763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
...
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
....
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
....
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
....
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
....
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
....
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
....
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
....
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
....
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
....
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
....
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
....
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
....
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
....
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
....
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
....
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
....
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
....
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
....
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365

9366
9367

9368
9369
9370
9371
9372
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c13.db
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
}]} {}

do_catchsql_test 13.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c14b.db
................................................................................
|     48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00   ................
|     64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00   p...........p...
| end c16.db
}]} {}

do_catchsql_test 15.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {/*malformed database schema*/}

#---------------------------------------------------------------------------
#
reset_db
do_test 16.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
................................................................................
|    448: 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53   TUAL TABLE t1 US
|    464: 49 4e 47 20 66 74 73 35 28 61 2c 62 2c 63 29 00   ING fts5(a,b,c).
|    480: 00 00 39 00 00 00 00 00 00 00 00 00 00 00 00 00   ..9.............
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-fed6e90021ba5d.db
}]} {}

do_catchsql_test 33.1 {
  CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
  CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
  CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance');
} {/*malformed database schema*/}

do_catchsql_test 33.2 {
  SELECT * FROM t2;
} {/*malformed database schema*/}

do_catchsql_test 33.3 {
  SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term;
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 34.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename crash-a60a9da4c8932f.db
................................................................................
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end null-memcmp-param-1..db
}]} {}

do_catchsql_test 37.1 {
  SELECT * FROM t3;
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 37a.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(b, c);
  INSERT INTO t1 VALUES('a', 'b');
  SELECT quote(block) FROM t1_data WHERE rowid=10;
} {X'000000000101010001010101'}

do_execsql_test 37a.1 {
  UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
  SELECT rowid FROM t1('a');
} {1}

#-------------------------------------------------------------------------
reset_db 
do_execsql_test 38.0 {
................................................................................
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end crash-fd2a1313e5b5e9.db
}]} {}

do_catchsql_test 38.1 {
  UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*';
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 39.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
................................................................................
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
| end crash2.txt.db
}]} {}

do_catchsql_test 40.1 {
  BEGIN;
  INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf');
  INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033');
  INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7');
} {/*malformed database schema*/}

do_catchsql_test 40.2 {
  INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44);
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
  REPLACE INTO t1_data VALUES(1,X'255a5824');
  REPLACE INTO t1_data VALUES(10,X'0a1000000102020002010101020101');
................................................................................
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
| end 89028ffd2c29b679e250.db
}]} {}

do_catchsql_test 43.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 44.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(a,b unindexed,c,tokenize="porter ascii");
  REPLACE INTO t1_data VALUES(1,X'03090009');
  REPLACE INTO t1_data VALUES(10,X'000000000103030003010101020101030101');
................................................................................
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
  INSERT INTO t1(t1, rank) VALUES('merge', 5);
} {/*malformed database schema*/}

#--------------------------------------------------------------------------
reset_db
do_test 46.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-1ee8bd451dd1ad.db
................................................................................
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end crash-1ee8bd451dd1ad.db
}]} {}

do_catchsql_test 46.1 {
  SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*');
} {/*malformed database schema*/}

#--------------------------------------------------------------------------
reset_db
do_test 47.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename 4b6fc659283f2735616c.db
................................................................................
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end 4b6fc659283f2735616c.db
}]} {}

do_catchsql_test 47.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {/*malformed database schema*/}

do_catchsql_test 47.2 {
  SELECT count(*) FROM (
      SELECT snippet(t1, -1, '.', '..', '[', 50), 
      highlight(t1, 2, '[', ']') FROM t1('g h') 
      WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank
  )
} {/*malformed database schema*/}

#--------------------------------------------------------------------------
reset_db
do_test 48.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-44a8305b4bd86f.db
................................................................................
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-2b92f77ddfe191.db
}]} {}

do_catchsql_test 52.1 {
  SELECT fts5_decode(id, block) FROM t1_data;
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 53.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-dbe9b7614da103.db
................................................................................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 0c e9   ................
| end crash-dbe9b7614da103.db
}]} {}

do_catchsql_test 53.1 {
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10)
    INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 54.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-03a1855566d9ae.db
................................................................................
|      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
|   4080: 00 00 23 03 02 01 03 03 02 02 01 02 02 00 f2 09   ..#.............
| end crash-03a1855566d9ae.db
}]} {}

do_catchsql_test 54.1 {
  SELECT rowid==-1 FROM t1('t*');
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 55.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-b366b5ac0d3887.db
................................................................................
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 77 72   .........+intewr
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end crash-b366b5ac0d3887.db
}]} {}

do_catchsql_test 55.1 {
  SAVEPOINT one;
  DELETE FROM t1 WHERE a MATCH 'ts';
} {/*malformed database schema*/}

do_execsql_test 55.2 {
  ROLLBACK TO one;
}

#-------------------------------------------------------------------------
reset_db
................................................................................
  # may return SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. This is because
  # the corrupt db in the test over-reads the page buffer slightly, with
  # different results depending on whether or not the page-cache is in use.
  if {$res=="1 {constraint failed}"} {
    set res "1 {database disk image is malformed}"
  }
  set res
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 57.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename x.db
................................................................................
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end x.db
}]} {}

do_catchsql_test 57.1 {
  INSERT INTO t1(t1) VALUES('optimize')
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
reset_db
do_test 58.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
................................................................................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|   4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00   ..#.............
| end crash-5a5acd0ab42d31.db
}]} {}

do_catchsql_test 58.1 {
  SELECT * FROM t1('t*');
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
do_test 59.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-96b136358d01ec.db
................................................................................
|   4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01   ................
| page 7 offset 24576
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-e5fa281edabddf.db
}]} {}

do_catchsql_test 61.1 {
  CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' );
} {/*malformed database schema*/}

do_catchsql_test 61.2 {
  SELECT * FROM t3 ORDER BY rowid;
} {/*malformed database schema*/}

breakpoint
#-------------------------------------------------------------------------
do_test 62.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
................................................................................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-44942694542e1e.db
}]} {}

do_catchsql_test 62.1 {
  WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72)
    INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
} {/*malformed database schema*/}

#---------------------------------------------------------------------------
do_test 63.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-8230e6c3b368f5.db
................................................................................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 08 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| end crash-8230e6c3b368f5.db
}]} {}

do_catchsql_test 63.1 {
  SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
} {/*malformed database schema*/}

do_catchsql_test 63.2 {
  INSERT INTO t1(t1) VALUES('optimize');
} {/*malformed database schema*/}


do_catchsql_test 63.3 {
  SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';

} {/*malformed database schema*/}

sqlite3_fts5_may_be_corrupt 0
finish_test

Changes to ext/fts5/test/fts5rank.test.

157
158
159
160
161
162
163
164


















165
  )
  INSERT INTO ttt SELECT 'word ' || i FROM s;
}

do_execsql_test 5.1 {
  SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}



















finish_test








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

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
  )
  INSERT INTO ttt SELECT 'word ' || i FROM s;
}

do_execsql_test 5.1 {
  SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE "My.Table" USING fts5(Text);

  INSERT INTO "My.Table" VALUES ('hello this is a test');
  INSERT INTO "My.Table" VALUES ('of trying to order by');
  INSERT INTO "My.Table" VALUES ('rank on an fts5 table');
  INSERT INTO "My.Table" VALUES ('that have periods in');
  INSERT INTO "My.Table" VALUES ('the table names.');
  INSERT INTO "My.Table" VALUES ('table table table');
}
do_execsql_test 6.1 {
  SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank;
} {
  {table table table} {the table names.} {rank on an fts5 table}
}

finish_test

Changes to ext/lsm1/Makefile.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
             $(LSMDIR)/lsm-test/lsmtest_main.c $(LSMDIR)/lsm-test/lsmtest_mem.c \
             $(LSMDIR)/lsm-test/lsmtest_tdb.c $(LSMDIR)/lsm-test/lsmtest_tdb3.c \
             $(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c


# all: lsm.so

LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB

lsm.so:	$(LSMOBJ)
	$(TCCX) -shared -o lsm.so $(LSMOBJ)

%.o:	$(LSMDIR)/%.c $(LSMHDR) sqlite3.h
	$(TCCX) $(LSMOPTS) -c $<
	
lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o
	# $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc
	$(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz







|


|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
             $(LSMDIR)/lsm-test/lsmtest_main.c $(LSMDIR)/lsm-test/lsmtest_mem.c \
             $(LSMDIR)/lsm-test/lsmtest_tdb.c $(LSMDIR)/lsm-test/lsmtest_tdb3.c \
             $(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c


# all: lsm.so

LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB

lsm.so:	$(LSMOBJ)
	$(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ)

%.o:	$(LSMDIR)/%.c $(LSMHDR) sqlite3.h
	$(TCCX) $(LSMOPTS) -c $<
	
lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o
	# $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc
	$(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz

Changes to ext/lsm1/lsm_vtab.c.

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
  int argIdx = -1;       /* Index of the key== constraint, or -1 if none */
  int iIdx2 = -1;        /* The index of the second key */
  int omit1 = 0;
  int omit2 = 0;

  const struct sqlite3_index_constraint *pConstraint;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint && idxNum<16; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->iColumn!=0 ) continue;
    switch( pConstraint->op ){
      case SQLITE_INDEX_CONSTRAINT_EQ: {
        if( idxNum>0 ){
          argIdx = i;
          iIdx2 = -1;







|







838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
  int argIdx = -1;       /* Index of the key== constraint, or -1 if none */
  int iIdx2 = -1;        /* The index of the second key */
  int omit1 = 0;
  int omit2 = 0;

  const struct sqlite3_index_constraint *pConstraint;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->iColumn!=0 ) continue;
    switch( pConstraint->op ){
      case SQLITE_INDEX_CONSTRAINT_EQ: {
        if( idxNum>0 ){
          argIdx = i;
          iIdx2 = -1;

Changes to ext/lsm1/test/lsm1_simple.test.

84
85
86
87
88
89
90



91






92


















































93
  INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL),
      (12,NULL,3.25,-559281390);
  SELECT quote(a), quote(b), quote(c), quote(d), '|' FROM x1;
} {'12' NULL 3.25 -559281390 | '15' 11 22 33 | '8' 'banjo' X'333231' NULL |}
do_execsql_test 211 {
  SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1;
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |}





























































finish_test







>
>
>

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

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
  INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL),
      (12,NULL,3.25,-559281390);
  SELECT quote(a), quote(b), quote(c), quote(d), '|' FROM x1;
} {'12' NULL 3.25 -559281390 | '15' 11 22 33 | '8' 'banjo' X'333231' NULL |}
do_execsql_test 211 {
  SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1;
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |}
do_execsql_test 212 {
  SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12';
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'}

#-------------------------------------------------------------------------
reset_db
forcedelete testlsm.db
load_lsm1_vtab db
do_execsql_test 300 {
  CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d);
}
do_eqp_test 310 {
  SELECT * FROM x1 WHERE a=?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}

do_eqp_test 320 {
  SELECT * FROM x1 WHERE a>?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:}

do_eqp_test 330 {
  SELECT * FROM x1 WHERE a<?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 3:}
do_eqp_test 340 {
  SELECT * FROM x1 WHERE a BETWEEN ? AND ?
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 1:}

#-------------------------------------------------------------------------
reset_db
forcedelete testlsm.db
load_lsm1_vtab db
do_execsql_test 400 {
  CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b);
  INSERT INTO x1 VALUES('one', 1);
  INSERT INTO x1 VALUES('two', 2);
  INSERT INTO x1 VALUES('three', 3);
  INSERT INTO x1 VALUES('four', 4);
  INSERT INTO x1 VALUES('five', 5);
}
do_execsql_test 410 {
  SELECT b FROM x1 WHERE a = 'two'
} {2}
do_execsql_test 411 {
  SELECT b FROM x1 WHERE a = 'one'
} {1}
do_execsql_test 412 {
  SELECT b FROM x1 WHERE a = 'five'
} {5}

do_execsql_test 420 {
  SELECT b FROM x1 WHERE a BETWEEN 'one' AND 'three';
} {1 3}
do_execsql_test 421 {
  SELECT b FROM x1 WHERE a BETWEEN 'five' AND 'two';
} {5 4 1 3 2}
do_execsql_test 421 {
  SELECT b FROM x1 WHERE a > 'five';
} {4 1 3 2}
do_execsql_test 421 {
  SELECT b FROM x1 WHERE a <= 'three';
} {3 1 4 5}

finish_test

Changes to main.mk.

523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE







<







523
524
525
526
527
528
529

530
531
532
533
534
535
536
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC

FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE

Changes to src/expr.c.

1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
....
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
....
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
....
4010
4011
4012
4013
4014
4015
4016






4017
4018

4019





4020

4021
4022
4023
4024
4025
4026
4027
    pNew->addrOpenEphm[0] = -1;
    pNew->addrOpenEphm[1] = -1;
    pNew->nSelectRow = p->nSelectRow;
    pNew->pWith = withDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
    pNew->pWin = 0;
    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
    if( p->pWin ) gatherSelectWindows(pNew);
#endif
    pNew->selId = p->selId;
    *pp = pNew;
    pp = &pNew->pPrior;
    pNext = pNew;
  }

................................................................................
    ** that columns affinity when building index keys. If <expr> is not
    ** a column, use numeric affinity.
    */
    char affinity;            /* Affinity of the LHS of the IN */
    int i;
    ExprList *pList = pExpr->x.pList;
    struct ExprList_item *pItem;
    int r1, r2, r3;
    affinity = sqlite3ExprAffinity(pLeft);
    if( affinity<=SQLITE_AFF_NONE ){
      affinity = SQLITE_AFF_BLOB;
    }
    if( pKeyInfo ){
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
................................................................................
      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
        sqlite3VdbeChangeToNoop(v, addrOnce);
        ExprClearProperty(pExpr, EP_Subrtn);
        addrOnce = 0;
      }

      /* Evaluate the expression and insert it into the temp table */
      r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
    }
    sqlite3ReleaseTempReg(pParse, r1);
    sqlite3ReleaseTempReg(pParse, r2);
  }
  if( pKeyInfo ){
    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  }
................................................................................
    }

    case TK_VECTOR: {
      sqlite3ErrorMsg(pParse, "row value misused");
      break;
    }







    case TK_IF_NULL_ROW: {
      int addrINR;

      addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);





      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);

      sqlite3VdbeJumpHere(v, addrINR);
      sqlite3VdbeChangeP3(v, addrINR, inReg);
      break;
    }

    /*
    ** Form A:







|







 







|







 







|
|
|







 







>
>
>
>
>
>


>

>
>
>
>
>

>







1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
....
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
....
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
....
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
    pNew->addrOpenEphm[0] = -1;
    pNew->addrOpenEphm[1] = -1;
    pNew->nSelectRow = p->nSelectRow;
    pNew->pWith = withDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
    pNew->pWin = 0;
    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
    if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
#endif
    pNew->selId = p->selId;
    *pp = pNew;
    pp = &pNew->pPrior;
    pNext = pNew;
  }

................................................................................
    ** that columns affinity when building index keys. If <expr> is not
    ** a column, use numeric affinity.
    */
    char affinity;            /* Affinity of the LHS of the IN */
    int i;
    ExprList *pList = pExpr->x.pList;
    struct ExprList_item *pItem;
    int r1, r2;
    affinity = sqlite3ExprAffinity(pLeft);
    if( affinity<=SQLITE_AFF_NONE ){
      affinity = SQLITE_AFF_BLOB;
    }
    if( pKeyInfo ){
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
................................................................................
      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
        sqlite3VdbeChangeToNoop(v, addrOnce);
        ExprClearProperty(pExpr, EP_Subrtn);
        addrOnce = 0;
      }

      /* Evaluate the expression and insert it into the temp table */
      sqlite3ExprCode(pParse, pE2, r1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
    }
    sqlite3ReleaseTempReg(pParse, r1);
    sqlite3ReleaseTempReg(pParse, r2);
  }
  if( pKeyInfo ){
    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  }
................................................................................
    }

    case TK_VECTOR: {
      sqlite3ErrorMsg(pParse, "row value misused");
      break;
    }

    /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions
    ** that derive from the right-hand table of a LEFT JOIN.  The
    ** Expr.iTable value is the table number for the right-hand table.
    ** The expression is only evaluated if that table is not currently
    ** on a LEFT JOIN NULL row.
    */
    case TK_IF_NULL_ROW: {
      int addrINR;
      u8 okConstFactor = pParse->okConstFactor;
      addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
      /* Temporarily disable factoring of constant expressions, since
      ** even though expressions may appear to be constant, they are not
      ** really constant because they originate from the right-hand side
      ** of a LEFT JOIN. */
      pParse->okConstFactor = 0;
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
      pParse->okConstFactor = okConstFactor;
      sqlite3VdbeJumpHere(v, addrINR);
      sqlite3VdbeChangeP3(v, addrINR, inReg);
      break;
    }

    /*
    ** Form A:

Changes to src/loadext.c.

457
458
459
460
461
462
463
464


465
466
467
468
469
470
471
#ifdef SQLITE_ENABLE_NORMALIZE
  sqlite3_normalized_sql,
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind


};

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.







|
>
>







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
#ifdef SQLITE_ENABLE_NORMALIZE
  sqlite3_normalized_sql,
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind,
  /* Version 3.30.0 and later */
  sqlite3_drop_modules,
};

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.

Changes to src/pragma.c.

1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
    for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
      CollSeq *pColl = (CollSeq *)sqliteHashData(p);
      sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
    }
  }
  break;

#ifdef SQLITE_INTROSPECTION_PRAGMAS
  case PragTyp_FUNCTION_LIST: {
    int i;
    HashElem *j;
    FuncDef *p;
    pParse->nMem = 2;
    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){







|







1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
    for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
      CollSeq *pColl = (CollSeq *)sqliteHashData(p);
      sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
    }
  }
  break;

#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
  case PragTyp_FUNCTION_LIST: {
    int i;
    HashElem *j;
    FuncDef *p;
    pParse->nMem = 2;
    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){

Changes to src/pragma.h.

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
...
664
665
666
667
668
669
670
671
 {/* zName:     */ "fullfsync",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_FullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "function_list",
  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 41, 2,
  /* iArg:      */ 0 },
#endif
#endif
................................................................................
  /* ePragTyp:  */ PragTyp_MMAP_SIZE,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "module_list",
  /* ePragTyp:  */ PragTyp_MODULE_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 9, 1,
  /* iArg:      */ 0 },
#endif
#endif
................................................................................
 {/* zName:     */ "parser_trace",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_ParserTrace },
#endif
#endif
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "pragma_list",
  /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 9, 1,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
................................................................................
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 62 on by default, 81 total. */







|







 







|







 







|







 







|
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
...
664
665
666
667
668
669
670
671
 {/* zName:     */ "fullfsync",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_FullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "function_list",
  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 41, 2,
  /* iArg:      */ 0 },
#endif
#endif
................................................................................
  /* ePragTyp:  */ PragTyp_MMAP_SIZE,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "module_list",
  /* ePragTyp:  */ PragTyp_MODULE_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 9, 1,
  /* iArg:      */ 0 },
#endif
#endif
................................................................................
 {/* zName:     */ "parser_trace",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_ParserTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "pragma_list",
  /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 9, 1,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
................................................................................
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 65 on by default, 81 total. */

Changes to src/shell.c.in.

3647
3648
3649
3650
3651
3652
3653

3654
3655
3656
3657
3658
3659
3660
....
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
....
6919
6920
6921
6922
6923
6924
6925

6926
6927
6928
6929
6930
6931
6932
....
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
....
9403
9404
9405
9406
9407
9408
9409


9410
9411
9412
9413
9414
9415







9416
9417

9418
9419
9420
9421
9422
9423
9424
  "    --stmt                  Trace statement execution (SQLITE_TRACE_STMT)",
  "    --profile               Profile statements (SQLITE_TRACE_PROFILE)",
  "    --row                   Trace each row (SQLITE_TRACE_ROW)",
  "    --close                 Trace connection close (SQLITE_TRACE_CLOSE)",
#endif /* SQLITE_OMIT_TRACE */
#ifdef SQLITE_DEBUG
  ".unmodule NAME ...       Unregister virtual table modules",

#endif
  ".vfsinfo ?AUX?           Information about the top-level VFS",
  ".vfslist                 List all available VFSes",
  ".vfsname ?AUX?           Print the name of the VFS stack",
  ".width NUM1 NUM2 ...     Set column widths for \"column\" mode",
  "     Negative values right-justify",
};
................................................................................
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int do_meta_command(char *zLine, ShellState *p){
  int h = 1;
  int nArg = 0;
  int n, c;
  int rc = 0;
  char *azArg[50];

#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( p->expert.pExpert ){
    expertFinish(p, 1, 0);
  }
#endif

  /* Parse the input line into tokens.
  */
  while( zLine[h] && nArg<ArraySize(azArg) ){
    while( IsSpace(zLine[h]) ){ h++; }
    if( zLine[h]==0 ) break;
    if( zLine[h]=='\'' || zLine[h]=='"' ){
      int delim = zLine[h++];
      azArg[nArg++] = &zLine[h];
      while( zLine[h] && zLine[h]!=delim ){
        if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
................................................................................
    }else{
      azArg[nArg++] = &zLine[h];
      while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
      if( zLine[h] ) zLine[h++] = 0;
      resolve_backslashes(azArg[nArg-1]);
    }
  }


  /* Process the input line.
  */
  if( nArg==0 ) return 0; /* no tokens, no error */
  n = strlen30(azArg[0]);
  c = azArg[0][0];
  clearTempFile(p);
................................................................................
        appendText(&sSelect, " AS snum, ", 0);
        appendText(&sSelect, zDb, '\'');
        appendText(&sSelect, " AS sname FROM ", 0);
        appendText(&sSelect, zDb, quoteChar(zDb));
        appendText(&sSelect, ".sqlite_master", 0);
      }
      sqlite3_finalize(pStmt);
#ifdef SQLITE_INTROSPECTION_PRAGMAS
      if( zName ){
        appendText(&sSelect,
           " UNION ALL SELECT shell_module_schema(name),"
           " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0);
      }
#endif
      appendText(&sSelect, ") WHERE ", 0);
................................................................................
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#ifdef SQLITE_DEBUG
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;


    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule NAME ...\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);







    for(ii=1; ii<nArg; ii++){
      sqlite3_create_module(p->db, azArg[ii], 0, 0);

    }
  }else
#endif

#if SQLITE_USER_AUTHENTICATION
  if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
    if( nArg<2 ){







>







 







|









|







 







>







 







|







 







>
>

|




>
>
>
>
>
>
>
|
|
>







3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
....
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
....
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
....
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
....
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
  "    --stmt                  Trace statement execution (SQLITE_TRACE_STMT)",
  "    --profile               Profile statements (SQLITE_TRACE_PROFILE)",
  "    --row                   Trace each row (SQLITE_TRACE_ROW)",
  "    --close                 Trace connection close (SQLITE_TRACE_CLOSE)",
#endif /* SQLITE_OMIT_TRACE */
#ifdef SQLITE_DEBUG
  ".unmodule NAME ...       Unregister virtual table modules",
  "    --allexcept             Unregister everything except those named",
#endif
  ".vfsinfo ?AUX?           Information about the top-level VFS",
  ".vfslist                 List all available VFSes",
  ".vfsname ?AUX?           Print the name of the VFS stack",
  ".width NUM1 NUM2 ...     Set column widths for \"column\" mode",
  "     Negative values right-justify",
};
................................................................................
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int do_meta_command(char *zLine, ShellState *p){
  int h = 1;
  int nArg = 0;
  int n, c;
  int rc = 0;
  char *azArg[52];

#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( p->expert.pExpert ){
    expertFinish(p, 1, 0);
  }
#endif

  /* Parse the input line into tokens.
  */
  while( zLine[h] && nArg<ArraySize(azArg)-1 ){
    while( IsSpace(zLine[h]) ){ h++; }
    if( zLine[h]==0 ) break;
    if( zLine[h]=='\'' || zLine[h]=='"' ){
      int delim = zLine[h++];
      azArg[nArg++] = &zLine[h];
      while( zLine[h] && zLine[h]!=delim ){
        if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
................................................................................
    }else{
      azArg[nArg++] = &zLine[h];
      while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
      if( zLine[h] ) zLine[h++] = 0;
      resolve_backslashes(azArg[nArg-1]);
    }
  }
  azArg[nArg] = 0;

  /* Process the input line.
  */
  if( nArg==0 ) return 0; /* no tokens, no error */
  n = strlen30(azArg[0]);
  c = azArg[0][0];
  clearTempFile(p);
................................................................................
        appendText(&sSelect, " AS snum, ", 0);
        appendText(&sSelect, zDb, '\'');
        appendText(&sSelect, " AS sname FROM ", 0);
        appendText(&sSelect, zDb, quoteChar(zDb));
        appendText(&sSelect, ".sqlite_master", 0);
      }
      sqlite3_finalize(pStmt);
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
      if( zName ){
        appendText(&sSelect,
           " UNION ALL SELECT shell_module_schema(name),"
           " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0);
      }
#endif
      appendText(&sSelect, ") WHERE ", 0);
................................................................................
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#ifdef SQLITE_DEBUG
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;
    int lenOpt;
    char *zOpt;
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    zOpt = azArg[1];
    if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
    lenOpt = (int)strlen(zOpt);
    if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
      assert( azArg[nArg]==0 );
      sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
    }else{
      for(ii=1; ii<nArg; ii++){
        sqlite3_create_module(p->db, azArg[ii], 0, 0);
      }
    }
  }else
#endif

#if SQLITE_USER_AUTHENTICATION
  if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
    if( nArg<2 ){

Changes to src/sqlite.h.in.

6635
6636
6637
6638
6639
6640
6641


6642
6643
6644
6645
6646
6647
6648
....
6649
6650
6651
6652
6653
6654
6655

















6656
6657
6658
6659
6660
6661
6662
** ^The sqlite3_create_module()
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
**
** ^If the third parameter (the pointer to the sqlite3_module object) is
** NULL then no new module is create and any existing modules with the
** same name are dropped.


*/
int sqlite3_create_module(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData          /* Client data for xCreate/xConnect */
);
................................................................................
int sqlite3_create_module_v2(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData,         /* Client data for xCreate/xConnect */
  void(*xDestroy)(void*)     /* Module destructor function */
);


















/*
** CAPI3REF: Virtual Table Instance Object
** KEYWORDS: sqlite3_vtab
**
** Every [virtual table module] implementation uses a subclass
** of this object to describe a particular instance







>
>







 







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







6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
....
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
** ^The sqlite3_create_module()
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
**
** ^If the third parameter (the pointer to the sqlite3_module object) is
** NULL then no new module is create and any existing modules with the
** same name are dropped.
**
** See also: [sqlite3_drop_modules()]
*/
int sqlite3_create_module(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData          /* Client data for xCreate/xConnect */
);
................................................................................
int sqlite3_create_module_v2(
  sqlite3 *db,               /* SQLite connection to register module with */
  const char *zName,         /* Name of the module */
  const sqlite3_module *p,   /* Methods for the module */
  void *pClientData,         /* Client data for xCreate/xConnect */
  void(*xDestroy)(void*)     /* Module destructor function */
);

/*
** CAPI3REF: Remove Unnecessary Virtual Table Implementations
** METHOD: sqlite3
**
** ^The sqlite3_drop_modules(D,L) interface removes all virtual
** table modules from database connection D except those named on list L.
** The L parameter must be either NULL or a pointer to an array of pointers
** to strings where the array is terminated by a single NULL pointer.
** ^If the L parameter is NULL, then all virtual table modules are removed.
**
** See also: [sqlite3_create_module()]
*/
int sqlite3_drop_modules(
  sqlite3 *db,                /* Remove modules from this connection */
  const char **azKeep         /* Except, do not remove the ones named here */
);

/*
** CAPI3REF: Virtual Table Instance Object
** KEYWORDS: sqlite3_vtab
**
** Every [virtual table module] implementation uses a subclass
** of this object to describe a particular instance

Changes to src/sqlite3ext.h.

318
319
320
321
322
323
324


325
326
327
328
329
330
331
...
610
611
612
613
614
615
616


617
618
619
620
621
622
623
                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
                            void(*xDestroy)(void*));
  /* Version 3.26.0 and later */
  const char *(*normalized_sql)(sqlite3_stmt*);
  /* Version 3.28.0 and later */
  int (*stmt_isexplain)(sqlite3_stmt*);
  int (*value_frombind)(sqlite3_value*);


};

/*
** This is the function signature used for all extension entry points.  It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
................................................................................
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain         sqlite3_api->isexplain
#define sqlite3_value_frombind         sqlite3_api->frombind


#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */

#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  /* This case when the file really is being compiled as a loadable 
  ** extension */
# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;







>
>







 







>
>







318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
...
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
                            void(*xDestroy)(void*));
  /* Version 3.26.0 and later */
  const char *(*normalized_sql)(sqlite3_stmt*);
  /* Version 3.28.0 and later */
  int (*stmt_isexplain)(sqlite3_stmt*);
  int (*value_frombind)(sqlite3_value*);
  /* Version 3.30.0 and later */
  int (*drop_modules)(sqlite3*,const char**);
};

/*
** This is the function signature used for all extension entry points.  It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
................................................................................
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain         sqlite3_api->isexplain
#define sqlite3_value_frombind         sqlite3_api->frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules           sqlite3_api->drop_modules
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */

#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  /* This case when the file really is being compiled as a loadable 
  ** extension */
# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/test1.c.

1105
1106
1107
1108
1109
1110
1111

























1112
1113
1114
1115
1116
1117
1118
....
7856
7857
7858
7859
7860
7861
7862

7863
7864
7865
7866
7867
7868
7869
  }
#endif

  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  return TCL_OK;
}


























/*
** Routines to implement the x_count() aggregate function.
**
** x_count() counts the number of non-null arguments.  But there are
** some twists for testing purposes.
**
................................................................................
#ifndef SQLITE_OMIT_GET_TABLE
     { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
#endif
     { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
     { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
     { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },

     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
     { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
     { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
     { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
     { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
     { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },







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







 







>







1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
....
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
  }
#endif

  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  return TCL_OK;
}

/*
** Usage:  sqlite3_drop_modules DB ?NAME ...?
**
** Invoke the sqlite3_drop_modules(D,L) interface on database
** connection DB, in order to drop all modules except those named in
** the argument.
*/
static int SQLITE_TCLAPI test_drop_modules(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite3 *db;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " DB\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
**
** x_count() counts the number of non-null arguments.  But there are
** some twists for testing purposes.
**
................................................................................
#ifndef SQLITE_OMIT_GET_TABLE
     { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
#endif
     { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
     { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
     { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
     { "sqlite3_drop_modules",          (Tcl_CmdProc*)test_drop_modules     },
     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
     { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
     { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
     { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
     { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
     { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },

Changes to src/vtab.c.

68
69
70
71
72
73
74

75
76
77
78
79
80
81
...
127
128
129
130
131
132
133






















134
135
136
137
138
139
140
  pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
  if( pDel ){
    if( pDel==pMod ){
      sqlite3OomFault(db);
      sqlite3DbFree(db, pDel);
      pMod = 0;
    }else{

      sqlite3VtabModuleUnref(db, pDel);
    }
  }
  return pMod;
}

/*
................................................................................
  void (*xDestroy)(void *)        /* Module destructor function */
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return createModule(db, zName, pModule, pAux, xDestroy);
}























/*
** Decrement the reference count on a Module object.  Destroy the
** module when the reference count reaches zero.
*/
void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){
  assert( pMod->nRefModule>0 );







>







 







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







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
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
  pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
  if( pDel ){
    if( pDel==pMod ){
      sqlite3OomFault(db);
      sqlite3DbFree(db, pDel);
      pMod = 0;
    }else{
      sqlite3VtabEponymousTableClear(db, pDel);
      sqlite3VtabModuleUnref(db, pDel);
    }
  }
  return pMod;
}

/*
................................................................................
  void (*xDestroy)(void *)        /* Module destructor function */
){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
  return createModule(db, zName, pModule, pAux, xDestroy);
}

/*
** External API to drop all virtual-table modules, except those named
** on the azNames list.
*/
int sqlite3_drop_modules(sqlite3 *db, const char** azNames){
  HashElem *pThis, *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){
    Module *pMod = (Module*)sqliteHashData(pThis);
    pNext = sqliteHashNext(pThis);
    if( azNames ){
      int ii;
      for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){}
      if( azNames[ii]!=0 ) continue;
    }
    createModule(db, pMod->zName, 0, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Decrement the reference count on a Module object.  Destroy the
** module when the reference count reaches zero.
*/
void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){
  assert( pMod->nRefModule>0 );

Changes to src/where.c.

3762
3763
3764
3765
3766
3767
3768
3769



3770
3771
3772
3773
3774
3775

3776

3777

3778
3779
3780
3781
3782
3783
3784
        assert( j>=pLoop->u.btree.nEq 
            || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
        );
        if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
          u16 eOp = pLoop->aLTerm[j]->eOperator;

          /* Skip over == and IS and ISNULL terms.  (Also skip IN terms when
          ** doing WHERE_ORDERBY_LIMIT processing). 



          **
          ** If the current term is a column of an ((?,?) IN (SELECT...)) 
          ** expression for which the SELECT returns more than one column,
          ** check that it is the only column used by this loop. Otherwise,
          ** if it is one of two or more, none of the columns can be
          ** considered to match an ORDER BY term.  */

          if( (eOp & eqOpMask)!=0 ){

            if( eOp & WO_ISNULL ){

              testcase( isOrderDistinct );
              isOrderDistinct = 0;
            }
            continue;  
          }else if( ALWAYS(eOp & WO_IN) ){
            /* ALWAYS() justification: eOp is an equality operator due to the
            ** j<pLoop->u.btree.nEq constraint above.  Any equality other







|
>
>
>





|
>

>
|
>







3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
        assert( j>=pLoop->u.btree.nEq 
            || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
        );
        if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
          u16 eOp = pLoop->aLTerm[j]->eOperator;

          /* Skip over == and IS and ISNULL terms.  (Also skip IN terms when
          ** doing WHERE_ORDERBY_LIMIT processing).  Except, IS and ISNULL
          ** terms imply that the index is not UNIQUE NOT NULL in which case
          ** the loop need to be marked as not order-distinct because it can
          ** have repeated NULL rows.
          **
          ** If the current term is a column of an ((?,?) IN (SELECT...)) 
          ** expression for which the SELECT returns more than one column,
          ** check that it is the only column used by this loop. Otherwise,
          ** if it is one of two or more, none of the columns can be
          ** considered to match an ORDER BY term.
          */
          if( (eOp & eqOpMask)!=0 ){
            if( eOp & (WO_ISNULL|WO_IS) ){
              testcase( eOp & WO_ISNULL );
              testcase( eOp & WO_IS );
              testcase( isOrderDistinct );
              isOrderDistinct = 0;
            }
            continue;  
          }else if( ALWAYS(eOp & WO_IN) ){
            /* ALWAYS() justification: eOp is an equality operator due to the
            ** j<pLoop->u.btree.nEq constraint above.  Any equality other

Changes to src/wherecode.c.

1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
**
** If pExpr matches, then transform it into a reference to the index column
** that contains the value of pExpr.
*/
static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
  IdxExprTrans *pX = p->u.pIdxTrans;
  if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){

    pExpr->op = TK_COLUMN;
    pExpr->iTable = pX->iIdxCur;
    pExpr->iColumn = pX->iIdxCol;
    pExpr->y.pTab = 0;
    return WRC_Prune;
  }else{
    return WRC_Continue;







>







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
**
** If pExpr matches, then transform it into a reference to the index column
** that contains the value of pExpr.
*/
static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
  IdxExprTrans *pX = p->u.pIdxTrans;
  if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
    pExpr->affExpr = sqlite3ExprAffinity(pExpr);
    pExpr->op = TK_COLUMN;
    pExpr->iTable = pX->iIdxCur;
    pExpr->iColumn = pX->iIdxCol;
    pExpr->y.pTab = 0;
    return WRC_Prune;
  }else{
    return WRC_Continue;

Changes to test/affinity2.test.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
..
53
54
55
56
57
58
59
60


























61
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is type affinity in comparison operations.
#

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


do_execsql_test affinity2-100 {
  CREATE TABLE t1(
    xi INTEGER,
    xr REAL,
    xb BLOB,
    xn NUMERIC,
................................................................................
do_execsql_test affinity2-220 {
  SELECT rowid, xn==xt, xn==xb, xn==+xt FROM t1 ORDER BY rowid;
} {1 1 1 1 2 1 1 1 3 1 1 1}

do_execsql_test affinity2-300 {
  SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid;
} {1 1 1 0 2 1 1 1 3 0 1 1}



























finish_test







>







 








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

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
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
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is type affinity in comparison operations.
#

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

do_execsql_test affinity2-100 {
  CREATE TABLE t1(
    xi INTEGER,
    xr REAL,
    xb BLOB,
    xn NUMERIC,
................................................................................
do_execsql_test affinity2-220 {
  SELECT rowid, xn==xt, xn==xb, xn==+xt FROM t1 ORDER BY rowid;
} {1 1 1 1 2 1 1 1 3 1 1 1}

do_execsql_test affinity2-300 {
  SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid;
} {1 1 1 0 2 1 1 1 3 0 1 1}

#-------------------------------------------------------------------------
do_execsql_test 400 {
  CREATE TABLE ttt(c0, c1);
  CREATE INDEX ii ON ttt(CAST(c0 AS NUMERIC)); 
  INSERT INTO ttt VALUES('abc', '-1');
}
do_execsql_test 410 {
  SELECT * FROM ttt WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid; 
} {abc -1}
do_execsql_test 420 {
  SELECT * FROM ttt INDEXED BY ii WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid;
} {abc -1}

do_execsql_test 430 {
  CREATE TABLE t3(a, b, c INTEGER);
  CREATE INDEX t3ac ON t3(a, c-1);
  INSERT INTO t3 VALUES(1, 1, 1);
  INSERT INTO t3 VALUES(2, 1, 0);
  INSERT INTO t3 VALUES(3, 1, 1);
  INSERT INTO t3 VALUES(4, 1, 0);
  INSERT INTO t3 VALUES(5, 1, 1);
}
do_execsql_test 440 {
  SELECT * FROM t3 WHERE c='0' ORDER BY a;
} {2 1 0 4 1 0}

finish_test

Changes to test/distinct2.test.

270
271
272
273
274
275
276

277





278



















279

} {
  one 0 1
  one 1 1
  two 0 1
  two 1 1
}




























finish_test








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

>
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
} {
  one 0 1
  one 1 1
  two 0 1
  two 1 1
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3000 {
  CREATE TABLE t0 (c0, c1 NOT NULL DEFAULT 1, c2, PRIMARY KEY (c0, c1));
  INSERT INTO t0(c2) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);
  INSERT INTO t0(c2) VALUES('a');
}

do_execsql_test 3010 {
  SELECT DISTINCT * FROM t0 WHERE NULL IS t0.c0;
} {
  {} 1 {}
  {} 1 a
}

do_execsql_test 3020 {
  ANALYZE;
}

do_execsql_test 3030 {
  SELECT DISTINCT * FROM t0 WHERE NULL IS c0;
} {
  {} 1 {}
  {} 1 a
}

finish_test

Changes to test/fts3snippet.test.

557
558
559
560
561
562
563


564






















565
566
567

do_test 4.3 {
  llength [db one {
    SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E'
  }]
} {64}



























set sqlite_fts3_enable_parentheses 0
finish_test







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



557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591

do_test 4.3 {
  llength [db one {
    SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E'
  }]
} {64}

#-------------------------------------------------------------------------
# Request a snippet from a query with more than 64 phrases.
#
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE t5 USING fts3(x);
  INSERT INTO t5 VALUES('a1 a2 a3');
  INSERT INTO t5 VALUES('a4 a5 a6');
  INSERT INTO t5 VALUES('a70 a71 a72');
}

do_execsql_test 5.1 {
  SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH 
  'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' ||
  'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' ||
  'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' ||
  'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' ||
  'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' ||
  'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' ||
  'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' ||
  'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70'
} {
  {[a1] [a2] [a3]}
  {[a4] [a5] [a6]}
  {[a70] [a71] [a72]}
}

set sqlite_fts3_enable_parentheses 0
finish_test

Changes to test/in5.test.

244
245
246
247
248
249
250


251















252
  CREATE TABLE t9(a INTEGER PRIMARY KEY);
  INSERT INTO t9 VALUES (44), (45);
}
do_execsql_test 9.1 {
  SELECT * FROM t9 WHERE a IN (44, 45, 44, 45)
} {44 45}



















finish_test







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

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
  CREATE TABLE t9(a INTEGER PRIMARY KEY);
  INSERT INTO t9 VALUES (44), (45);
}
do_execsql_test 9.1 {
  SELECT * FROM t9 WHERE a IN (44, 45, 44, 45)
} {44 45}

#-------------------------------------------------------------------------
# Test that ticket c7a117190 is fixed.
#
reset_db
do_execsql_test 9.0 {
  CREATE TABLE t0(c0);
  CREATE VIEW v0(c0) AS SELECT LOWER(CAST('1e500' AS TEXT)) FROM t0;
  INSERT INTO t0(c0) VALUES (NULL);
}

do_execsql_test 9.1 {
  SELECT lower('1e500') FROM t0 WHERE rowid NOT IN (0, 0, lower('1e500'));
} {1e500}

do_execsql_test 9.2 {
  SELECT lower('1e500') FROM t0 WHERE rowid != lower('1e500');
} {1e500}

finish_test

Changes to test/join.test.

859
860
861
862
863
864
865
866















867
  CREATE TABLE t1(a INT);
  INSERT INTO t1(a) VALUES(1);
  CREATE TABLE t2(b INT);
  SELECT a, b
    FROM t1 LEFT JOIN t2 ON 0
   WHERE (b IS NOT NULL)=0;
} {1 {}}
















finish_test








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

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
  CREATE TABLE t1(a INT);
  INSERT INTO t1(a) VALUES(1);
  CREATE TABLE t2(b INT);
  SELECT a, b
    FROM t1 LEFT JOIN t2 ON 0
   WHERE (b IS NOT NULL)=0;
} {1 {}}

# 2019-08-17 ticket https://sqlite.org/src/tktview/6710d2f7a13a299728ab
# Ensure that constants that derive from the right-hand table of a LEFT JOIN
# are never factored out, since they are not really constant.
#
do_execsql_test join-17.100 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES(0),(1);
  SELECT * FROM t1 LEFT JOIN (SELECT abs(1) AS y FROM t1) ON x WHERE NOT(y='a');
} {1 1 1 1}
do_execsql_test join-17.110 {
  SELECT * FROM t1 LEFT JOIN (SELECT abs(1)+2 AS y FROM t1) ON x
   WHERE NOT(y='a');
} {1 3 1 3}

finish_test

Changes to test/pragma5.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#    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.
#
# This file implements tests for the PRAGMA command. Specifically,
# those pragmas enabled at build time by setting:
#
#   -DSQLITE_INTROSPECTION_PRAGMAS
#

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

if { [catch {db one "SELECT count(*) FROM pragma_function_list"}] } {







|

|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#    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.
#
# This file implements tests for the PRAGMA command. Specifically,
# those pragmas that are not disabled at build time by setting:
#
#   -DSQLITE_OMIT_INTROSPECTION_PRAGMAS
#

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

if { [catch {db one "SELECT count(*) FROM pragma_function_list"}] } {

Changes to test/windowfault.test.

219
220
221
222
223
224
225
226






















227
  }
} -test {
  faultsim_test_result [list 0 $::L]
}

catch {db close}
tvfs delete























finish_test








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

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
  }
} -test {
  faultsim_test_result [list 0 $::L]
}

catch {db close}
tvfs delete

reset_db
do_execsql_test 10.0 {
  CREATE TABLE t1(a, b, c, d);
  CREATE TABLE t2(a, b, c, d);
}

do_faultsim_test 1 -faults oom* -prep {
} -body {
  execsql {
    SELECT row_number() OVER win
    FROM t1
    WINDOW win AS (
      ORDER BY (
        SELECT percent_rank() OVER win2 FROM t2
        WINDOW win2 AS (ORDER BY a)
      )
    )
  }
} -test {
  faultsim_test_result {0 {}}
}

finish_test

Changes to tool/mkpragmatab.tcl.

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
  COLS: seq name file
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: function_list
  FLAG: Result0
  COLS: name builtin
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  IF:   defined(SQLITE_INTROSPECTION_PRAGMAS)

  NAME: module_list
  FLAG: Result0
  COLS: name
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_VIRTUALTABLE)
  IF:   defined(SQLITE_INTROSPECTION_PRAGMAS)

  NAME: pragma_list
  FLAG: Result0
  COLS: name
  IF:   defined(SQLITE_INTROSPECTION_PRAGMAS)

  NAME: collation_list
  FLAG: Result0
  COLS: seq name
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: foreign_key_list







|






|




|







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
  COLS: seq name file
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: function_list
  FLAG: Result0
  COLS: name builtin
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)

  NAME: module_list
  FLAG: Result0
  COLS: name
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  IF:   !defined(SQLITE_OMIT_VIRTUALTABLE)
  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)

  NAME: pragma_list
  FLAG: Result0
  COLS: name
  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)

  NAME: collation_list
  FLAG: Result0
  COLS: seq name
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: foreign_key_list