Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5aa307e2a6 | |||
| c080422642 | |||
| 3e380a4485 | |||
| 37f906087b | |||
| 2fb960b545 | |||
| 8b471e7e79 | |||
| 6559e2cec7 | |||
| 6be95366c7 | |||
| bd8fcc130a | |||
| 6e11b16282 | |||
| 59a386ea03 | |||
| 3144df1264 | |||
| a5e906f307 | |||
| 210ec4c855 | |||
| af38cdbc08 | |||
| d5fbde80a2 | |||
| 7df7475d0d | |||
| 169dd928c5 | |||
| 5aa550cf3b |
@@ -0,0 +1,45 @@
|
||||
# 2014 June 17
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5leftjoin
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE vt USING fts5(x);
|
||||
INSERT INTO vt VALUES('abc');
|
||||
INSERT INTO vt VALUES('xyz');
|
||||
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES(1), (2);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT * FROM t1 LEFT JOIN (
|
||||
SELECT rowid AS rrr, * FROM vt WHERE vt MATCH 'abc'
|
||||
) ON t1.a = rrr
|
||||
} {1 1 abc 2 {} {}}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
SELECT * FROM t1 LEFT JOIN vt ON (vt MATCH 'abc')
|
||||
} {1 abc 2 abc}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ struct CsvReader {
|
||||
int n; /* Number of bytes in z */
|
||||
int nAlloc; /* Space allocated for z[] */
|
||||
int nLine; /* Current line number */
|
||||
int bNotFirst; /* True if prior text has been seen */
|
||||
char cTerm; /* Character that terminated the most recent field */
|
||||
size_t iIn; /* Next unread character in the input buffer */
|
||||
size_t nIn; /* Number of characters in the input buffer */
|
||||
@@ -91,6 +92,7 @@ static void csv_reader_init(CsvReader *p){
|
||||
p->n = 0;
|
||||
p->nAlloc = 0;
|
||||
p->nLine = 0;
|
||||
p->bNotFirst = 0;
|
||||
p->nIn = 0;
|
||||
p->zIn = 0;
|
||||
p->zErr[0] = 0;
|
||||
@@ -251,6 +253,21 @@ static char *csv_read_one_field(CsvReader *p){
|
||||
pc = c;
|
||||
}
|
||||
}else{
|
||||
/* If this is the first field being parsed and it begins with the
|
||||
** UTF-8 BOM (0xEF BB BF) then skip the BOM */
|
||||
if( (c&0xff)==0xef && p->bNotFirst==0 ){
|
||||
csv_append(p, (char)c);
|
||||
c = csv_getc(p);
|
||||
if( (c&0xff)==0xbb ){
|
||||
csv_append(p, (char)c);
|
||||
c = csv_getc(p);
|
||||
if( (c&0xff)==0xbf ){
|
||||
p->bNotFirst = 1;
|
||||
p->n = 0;
|
||||
return csv_read_one_field(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
while( c>',' || (c!=EOF && c!=',' && c!='\n') ){
|
||||
if( csv_append(p, (char)c) ) return 0;
|
||||
c = csv_getc(p);
|
||||
@@ -262,6 +279,7 @@ static char *csv_read_one_field(CsvReader *p){
|
||||
p->cTerm = (char)c;
|
||||
}
|
||||
if( p->z ) p->z[p->n] = 0;
|
||||
p->bNotFirst = 1;
|
||||
return p->z;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Add\sthe\s"-unsetnull\s1"\soption\sto\sthe\s"sqlite3"\scommand\sin\sthe\sTCL\sinterface.
|
||||
D 2017-06-26T16:13:20.034
|
||||
C Fix\sthe\sexprCompareVariable()\sroutine\sso\sthat\sit\sworks\sfor\snon-UTF8\stext.
|
||||
D 2017-06-29T01:23:12.291
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
|
||||
@@ -168,6 +168,7 @@ F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
|
||||
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
|
||||
F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
|
||||
F ext/fts5/test/fts5lastrowid.test 4fac1aba696dd6c956e03b0cf91f6f1f3aaec494
|
||||
F ext/fts5/test/fts5leftjoin.test 513ad7a7c053f8a6b7968ed6c84d1fc8c7a84fd29cfde0d14cc085ae6ca682c6
|
||||
F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
|
||||
F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3
|
||||
F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75
|
||||
@@ -214,7 +215,7 @@ F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a2
|
||||
F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d
|
||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d
|
||||
F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2
|
||||
F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
@@ -341,24 +342,24 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121
|
||||
F src/alter.c 850ede4e607f12fa25ea4f3cb6ece2b2e29d1aa50e3f786ce49d615788849552
|
||||
F src/analyze.c 0d0ccf7520a201d8747ea2f02c92c26e26f801bc161f714f27b9f7630dde0421
|
||||
F src/attach.c 3bd555e28382603e80d430dfebb2270f86e1e375b4c4be3e1ab1aec3a0c44943
|
||||
F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 430e34151e6ef37e42d3f956bb062907c80ff91e1380704b967b8c1a02a98f64
|
||||
F src/btree.c 00579ff9c2831d6f98cc993f8f2a34c0ff996e89b3cd2f27928f75796bc3a58a
|
||||
F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca
|
||||
F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610
|
||||
F src/build.c 88a8cdc11d1c081ed565aa3e795bdf9160f4556463b4c4555e9860b59dd80340
|
||||
F src/build.c b24e0889ba18ba0e93e03e2ef5c9f1a2ca043d77c5abbd3d333858a76b795da3
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c e9a6db1321c2353fe922533f202b85abb3084cdf569450abcabf55e21e104550
|
||||
F src/date.c cc42a41c7422389860d40419a5e3bce5eaf6e7835c3ba2677751dc653550a5c7
|
||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||
F src/delete.c 3213547e97b676c6fa79948b7a9ede4801ea04a01a2043241deafedf132ecf5d
|
||||
F src/expr.c 452c6f3aa656aabf3eefe96bb5f316b2c987fbc12c647964e4ed880f193ca31f
|
||||
F src/expr.c cc024ddd19aa37b6672caedab90e2a5ec69a4a1a97da94c2f1a0bd81cf0cd922
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333
|
||||
F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174
|
||||
@@ -367,10 +368,10 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 974499a3999d339a4c1ba8ef129a988d9f136b3789e423808b38cdc19d28adbe
|
||||
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
|
||||
F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9
|
||||
F src/main.c 18f2145d572069dae91161add89446aec680aab296492a92ae5afcc2fc7c6b5a
|
||||
F src/main.c 747ec45346c3826113bc081cafe1aa2df945e50540c4b3fb13ec02b5e231c3db
|
||||
F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@@ -394,28 +395,28 @@ F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 14f6982c470c05b8e85575c69e9c1712010602e20400f8670d8699e21283e0e4
|
||||
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
|
||||
F src/parse.y 0513387ce02fea97897d8caef82d45f347818593f24f1bdc48e0c530a8af122d
|
||||
F src/parse.y b13c9fc83cb634daf7fd5fef89127e8eafdf4904ab9a168d3e1862c5a3c7ae22
|
||||
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
|
||||
F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11
|
||||
F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
|
||||
F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371
|
||||
F src/pragma.h a8a949000214fefb6210330eed8ccbbb4f752619a9871f31b3dedd4a240277fd
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/pragma.h 99d3df4a3d2f12c5227ad403f767334910e6356325b6d155a9a99b4037093460
|
||||
F src/prepare.c a80a740b306a5fb2f2594d68776aade4ce1920687932e7c4dc0320ebdadcbb5d
|
||||
F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c adf3ef9843135b1383321ad751f16f5a40c3f37925154555a3e61653d2a954e8
|
||||
F src/resolve.c d1e69759e7a79c156c692793f5d16f82f9a60ce5e82efd95e4374b2423034946
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 35ccfae64cecfa843d54a5898c4ab7d6595ce03d147267fa5eecdc8eab39cd6a
|
||||
F src/shell.c 2026e88e7892ba177eae79936285d781f1c449f7a7b4e8d86fd02739d4ead26b
|
||||
F src/sqlite.h.in 67fa8bd29808e7988e0ce36c8d4c6043eb1727f94522fc612687aa5af51931e6
|
||||
F src/select.c 741937503c74d85e64828b63d5a4219d3cfce480a717efef635839606001b1ba
|
||||
F src/shell.c 227b86f2bdd707d0a177a4805a5c0b0378ef8337ab1ad04f5d79dc479568735a
|
||||
F src/sqlite.h.in 2555ff1b79a1aadeb4eb761740351dc3027fa08120bf84511633ba75a630e7a8
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
|
||||
F src/sqliteInt.h 34a54fb47de2da1465f3d3ba1cd373db880bd5d588b0fe862a073ecacd6ddaae
|
||||
F src/sqliteInt.h 37f1a9a3266aa7b11126585314cd98cf11ba6f174b1244de2221270107ea754d
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c bdf3b4386f15cfcf9ec91e9345e10a3a1a26cb9b1f17109dd0c88ac69f66828d
|
||||
F src/test1.c c99f0442918a7a5d5b68a95d6024c211989e6c782c15ced5a558994baaf76a5e
|
||||
F src/tclsqlite.c cbf6313f86400acdf7dbf55fcd218cd28d43110a1210967efbc4f250646f81c0
|
||||
F src/test1.c 735f7711e787f30ad4e0001220c580ce456d9f731e22e0e5f86dd5c7e41ccd4d
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
@@ -472,13 +473,13 @@ F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
|
||||
F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
|
||||
F src/vdbe.c 6783778df820f3e0c68289fe5d12ddd34168b0eb1acf248668fec6e2ea1012d5
|
||||
F src/vdbe.c 50f4f47bb190099b61fe87e239de17ad00636a522a271dd9b28329053091401d
|
||||
F src/vdbe.h 70a409d171d4e51b962f0d53abf15c33c404c6aa4c9d62fb3a931b5a62ba9615
|
||||
F src/vdbeInt.h cdcdabad4f5d6bf7a3beb826a7f33ee6f8f1cb220042bedd5b7d4bf2ea1d179f
|
||||
F src/vdbeapi.c c961d8d9e0f52e2df60a6ddbbccd7d99dc4d00103db7e53f77fcef44fbd23178
|
||||
F src/vdbeaux.c bc9b3228f6d99bef0d0ecaf3a0e0e8358b3873242d0d2fe944226de3fdf9521e
|
||||
F src/vdbeaux.c d7c7a57f59dc22c05e9a16177615f604fe73588b0ebdc84b540ba5efe3ada430
|
||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||
F src/vdbemem.c 94b17d851f31d4fd075d47d373d4b33ed3962a6ecb82cf385018025751091360
|
||||
F src/vdbemem.c 8d78df62becfd2dce3c317f64b32a94ecaff8346d814bc8b0b877b38a1ad3718
|
||||
F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
|
||||
@@ -486,10 +487,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
F src/walker.c d46044e7a5842560dfe7122d93ff5145dd4a96f4d0bf5ba5910a7731b8c01e79
|
||||
F src/where.c 74b0a05487e44e8c5d28ebe3bd77ca9719b1d5114235bed48079aee309a0bb4e
|
||||
F src/where.c 715b84912bf85d833ff558d6de51c0d0427483c1f5efe1bb6818d4e683f4869e
|
||||
F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20
|
||||
F src/wherecode.c 339ee802d9d311acf0cba8b5a9a092e167ef71c3a777d4b3e57de25d193251c7
|
||||
F src/whereexpr.c a2fe3811d45af45a5c6667caabc15e01054fe6228c64e86e1f7d2ba5ef5284f9
|
||||
F src/wherecode.c f17f5d51e372168db51af637e265aa5e80f99fcc81bfead96b66e71a7732bc62
|
||||
F src/whereexpr.c fa51927cc6830b9d3155cafa4e589452ec023fe313a56550d2079dca6c52fbd8
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -504,7 +505,7 @@ F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
|
||||
F test/analyze3.test 1dccda46a6c374018af617fba00bfe297a61d442
|
||||
F test/analyze3.test 8b3ef8ba6d1096b76c40e0925c0fe51e700d2b779cdda40914580de3f9b9d80f
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
||||
@@ -797,7 +798,7 @@ F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
|
||||
F test/fts3fault.test 3764ecffb3d341c5b05b3abe64153f385880035e67706ca2fc719e5d3352aedb
|
||||
F test/fts3fault2.test 536bbe01fe2946ec24b063a5eee813e8fd90354a6ca0b8f941d299c405edd17e
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
F test/fts3join.test 34750f3ce1e29b2749eaf0f1be2fa6301c5d50da
|
||||
F test/fts3join.test a758accc808cebaef8d622aac07994a2eae15c40eebc40888dcbbabc6f6bafb6
|
||||
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
||||
F test/fts3matchinfo.test ce864e0bd92429df8008f31cf557269ba172482a
|
||||
F test/fts3misc.test 66e7b59576ce2c795f0baff6d47f7f6f57e6f41101cf85fad05989e43bb060dd
|
||||
@@ -885,6 +886,7 @@ F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7
|
||||
F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
|
||||
F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7
|
||||
F test/indexexpr2.test 68ee9dbe83fcf85e50f4d0bd1f742a082496f2ee5153f4be2a1861db84462bf7
|
||||
@@ -928,7 +930,7 @@ F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c d2b8cfc91047ebf6cac4f3a04f19c3a864e4ecfd683bbb65c395df450b8dc79c
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302
|
||||
F test/like.test e7b1e724c731a219c4338e37cfe2c5861cd1cd7a856bbdd1d6045ae4f83dc7c7
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
@@ -1130,7 +1132,7 @@ F test/shell1.test 65f55c120ab289bc72ec0e534d104e078124d94aeac75dc7444c338c4d84f
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9
|
||||
F test/shell5.test 0d973866d0df8501486a840f51d1502ab0d9b38ca12c9b242ee26adc788af576
|
||||
F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772
|
||||
F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
@@ -1187,7 +1189,7 @@ F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 464d820179bb34da9126a15c61b3a26d32fb3bfd01efa77f66fbdf4d5c02e34c
|
||||
F test/tclsqlite.test c3d7ac9449634b9f17fd048a3c0212e88a7448be810a9c5bd051acc1ffa00d2f
|
||||
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
||||
F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
@@ -1508,8 +1510,8 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
|
||||
F tool/lemon.c f4f1045743e12f86b132253a3192ef92c94bfceb7f41ac41b8e3b373aa78474e
|
||||
F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1
|
||||
F tool/lemon.c 5a04dff28578a67415cea5bf981b893c50cebfdd4388fb21254d1892525edfd8
|
||||
F tool/lempar.c f0dc07c2838febff4c34244651a6932fceb523065e6fe79bacfaa93019cc8cca
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
@@ -1521,7 +1523,7 @@ F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66e
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl bdd4c76449e9e0874ae7f0846868c42583e63b47a081b177a97f94e2b702b3e7
|
||||
F tool/mkpragmatab.tcl aa94395a91b5bd47022b7db0c08126f047887e0d299cc19ec1c23a9e5b136961
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 226da6d794d7d43a31e159a6fa89db867bf1f5eafe4b37d031222287ef8dbadc
|
||||
@@ -1583,7 +1585,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P c8186874b3fec737445ad5c4ba3eaecd922af664b387d89dc31eea60476a0294
|
||||
R b62dc4f8740bb059f00fcbad381d5bd0
|
||||
P b959c6297c151150ea2dca24aa1f68f3bd76dd6620eb6c03f8dfa59fdd5c13b2
|
||||
R 12b2a850985daf065d11c67446406f71
|
||||
U drh
|
||||
Z 6d4208a1d8ce288a47a0e77bfe0eac01
|
||||
Z c02c38fdab65d893d3a1e810ddd8aa5b
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
cbe441b231397a9b775df71373ed5df9b1934a4bc428f9e09274446f9c86b859
|
||||
25acd9658be792d686b3ebfaa8c3692f9830e043538ed0afecf97110a07758a4
|
||||
+1
-1
@@ -375,7 +375,7 @@ static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
|
||||
** Or, if zName is not a system table, zero is returned.
|
||||
*/
|
||||
static int isSystemTable(Parse *pParse, const char *zName){
|
||||
if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
|
||||
if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+5
-5
@@ -152,7 +152,7 @@ static int hasSharedCacheTableLock(
|
||||
** Return true immediately.
|
||||
*/
|
||||
if( (pBtree->sharable==0)
|
||||
|| (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted))
|
||||
|| (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit))
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ static int hasReadConflicts(Btree *pBtree, Pgno iRoot){
|
||||
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
|
||||
if( p->pgnoRoot==iRoot
|
||||
&& p->pBtree!=pBtree
|
||||
&& 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted)
|
||||
&& 0==(p->pBtree->db->flags & SQLITE_ReadUncommit)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
|
||||
assert( sqlite3BtreeHoldsMutex(p) );
|
||||
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
|
||||
assert( p->db!=0 );
|
||||
assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
|
||||
assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 );
|
||||
|
||||
/* If requesting a write-lock, then the Btree must have an open write
|
||||
** transaction on this file. And, obviously, for this to be so there
|
||||
@@ -329,7 +329,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
|
||||
** obtain a read-lock using this function. The only read-lock obtained
|
||||
** by a connection in read-uncommitted mode is on the sqlite_master
|
||||
** table, and that lock is obtained in BtreeBeginTrans(). */
|
||||
assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
|
||||
assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK );
|
||||
|
||||
/* This function should only be called on a sharable b-tree after it
|
||||
** has been determined that no other b-tree holds a conflicting lock. */
|
||||
@@ -3021,7 +3021,7 @@ static int lockBtree(BtShared *pBt){
|
||||
pageSize-usableSize);
|
||||
return rc;
|
||||
}
|
||||
if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){
|
||||
if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto page1_init_failed;
|
||||
}
|
||||
|
||||
+3
-1
@@ -4185,7 +4185,9 @@ void sqlite3UniqueConstraint(
|
||||
assert( pIdx->aiColumn[j]>=0 );
|
||||
zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
|
||||
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
|
||||
sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
|
||||
sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
|
||||
sqlite3StrAccumAppend(&errMsg, ".", 1);
|
||||
sqlite3StrAccumAppendAll(&errMsg, zCol);
|
||||
}
|
||||
}
|
||||
zErr = sqlite3StrAccumFinish(&errMsg);
|
||||
|
||||
+65
-15
@@ -1829,7 +1829,7 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
|
||||
** it constant. */
|
||||
for(i=0; i<pGroupBy->nExpr; i++){
|
||||
Expr *p = pGroupBy->a[i].pExpr;
|
||||
if( sqlite3ExprCompare(pExpr, p, -1)<2 ){
|
||||
if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
|
||||
CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
|
||||
if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
|
||||
return WRC_Prune;
|
||||
@@ -4105,7 +4105,7 @@ int sqlite3ExprCodeAtInit(
|
||||
struct ExprList_item *pItem;
|
||||
int i;
|
||||
for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
|
||||
if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
|
||||
if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
|
||||
return pItem->u.iConstExprReg;
|
||||
}
|
||||
}
|
||||
@@ -4660,6 +4660,41 @@ void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
|
||||
sqlite3ExprDelete(db, pCopy);
|
||||
}
|
||||
|
||||
/*
|
||||
** Expression pVar is guaranteed to be an SQL variable. pExpr may be any
|
||||
** type of expression.
|
||||
**
|
||||
** If pExpr is a simple SQL value - an integer, real, string, blob
|
||||
** or NULL value - then the VDBE currently being prepared is configured
|
||||
** to re-prepare each time a new value is bound to variable pVar.
|
||||
**
|
||||
** Additionally, if pExpr is a simple SQL value and the value is the
|
||||
** same as that currently bound to variable pVar, non-zero is returned.
|
||||
** Otherwise, if the values are not the same or if pExpr is not a simple
|
||||
** SQL value, zero is returned.
|
||||
*/
|
||||
static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){
|
||||
int res = 0;
|
||||
int iVar;
|
||||
sqlite3_value *pL, *pR = 0;
|
||||
|
||||
sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
|
||||
if( pR ){
|
||||
iVar = pVar->iColumn;
|
||||
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
|
||||
pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
|
||||
if( pL ){
|
||||
if( sqlite3_value_type(pL)==SQLITE_TEXT ){
|
||||
sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
|
||||
}
|
||||
res = 0==sqlite3MemCompare(pL, pR, 0);
|
||||
}
|
||||
sqlite3ValueFree(pR);
|
||||
sqlite3ValueFree(pL);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
** Do a deep comparison of two expression trees. Return 0 if the two
|
||||
@@ -4682,12 +4717,22 @@ void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
|
||||
** this routine is used, it does not hurt to get an extra 2 - that
|
||||
** just might result in some slightly slower code. But returning
|
||||
** an incorrect 0 or 1 could lead to a malfunction.
|
||||
**
|
||||
** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
|
||||
** pParse->pReprepare can be matched against literals in pB. The
|
||||
** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
|
||||
** If pParse is NULL (the normal case) then any TK_VARIABLE term in
|
||||
** Argument pParse should normally be NULL. If it is not NULL and pA or
|
||||
** pB causes a return value of 2.
|
||||
*/
|
||||
int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||
int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
u32 combinedFlags;
|
||||
if( pA==0 || pB==0 ){
|
||||
return pB==pA ? 0 : 2;
|
||||
}
|
||||
if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
|
||||
return 0;
|
||||
}
|
||||
combinedFlags = pA->flags | pB->flags;
|
||||
if( combinedFlags & EP_IntValue ){
|
||||
if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
|
||||
@@ -4696,10 +4741,10 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||
return 2;
|
||||
}
|
||||
if( pA->op!=pB->op ){
|
||||
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
|
||||
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
|
||||
return 1;
|
||||
}
|
||||
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
|
||||
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
@@ -4714,8 +4759,8 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
|
||||
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
|
||||
if( combinedFlags & EP_xIsSelect ) return 2;
|
||||
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
|
||||
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
|
||||
if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
|
||||
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
|
||||
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
|
||||
if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
|
||||
if( pA->iColumn!=pB->iColumn ) return 2;
|
||||
@@ -4750,7 +4795,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
Expr *pExprA = pA->a[i].pExpr;
|
||||
Expr *pExprB = pB->a[i].pExpr;
|
||||
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
|
||||
if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
|
||||
if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -4760,7 +4805,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
** are ignored.
|
||||
*/
|
||||
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
|
||||
return sqlite3ExprCompare(
|
||||
return sqlite3ExprCompare(0,
|
||||
sqlite3ExprSkipCollate(pA),
|
||||
sqlite3ExprSkipCollate(pB),
|
||||
iTab);
|
||||
@@ -4782,24 +4827,29 @@ int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
|
||||
** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
|
||||
** Expr.iTable<0 then assume a table number given by iTab.
|
||||
**
|
||||
** If pParse is not NULL, then the values of bound variables in pE1 are
|
||||
** compared against literal values in pE2 and pParse->pVdbe->expmask is
|
||||
** modified to record which bound variables are referenced. If pParse
|
||||
** is NULL, then false will be returned if pE1 contains any bound variables.
|
||||
**
|
||||
** When in doubt, return false. Returning true might give a performance
|
||||
** improvement. Returning false might cause a performance reduction, but
|
||||
** it will always give the correct answer and is hence always safe.
|
||||
*/
|
||||
int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
|
||||
if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
|
||||
int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){
|
||||
if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
|
||||
return 1;
|
||||
}
|
||||
if( pE2->op==TK_OR
|
||||
&& (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
|
||||
|| sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
|
||||
&& (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
|
||||
|| sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
|
||||
Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
|
||||
testcase( pX!=pE1->pLeft );
|
||||
if( sqlite3ExprCompare(pX, pE2->pLeft, iTab)==0 ) return 1;
|
||||
if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -5040,7 +5090,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
*/
|
||||
struct AggInfo_func *pItem = pAggInfo->aFunc;
|
||||
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
|
||||
if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
|
||||
if( sqlite3ExprCompare(0, pItem->pExpr, pExpr, -1)==0 ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1898,7 +1898,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
||||
}
|
||||
if( pSrc->aiColumn[i]==XN_EXPR ){
|
||||
assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
|
||||
if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
|
||||
if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr,
|
||||
pDest->aColExpr->a[i].pExpr, -1)!=0 ){
|
||||
return 0; /* Different expressions in the index */
|
||||
}
|
||||
@@ -1910,7 +1910,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
||||
return 0; /* Different collating sequences */
|
||||
}
|
||||
}
|
||||
if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
|
||||
if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
|
||||
return 0; /* Different WHERE clauses */
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -127,11 +127,8 @@ exec_out:
|
||||
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && pzErrMsg ){
|
||||
int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
|
||||
*pzErrMsg = sqlite3Malloc(nErrMsg);
|
||||
if( *pzErrMsg ){
|
||||
memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
|
||||
}else{
|
||||
*pzErrMsg = sqlite3DbStrDup(0, sqlite3_errmsg(db));
|
||||
if( *pzErrMsg==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
sqlite3Error(db, SQLITE_NOMEM);
|
||||
}
|
||||
|
||||
@@ -811,6 +811,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
||||
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
|
||||
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
|
||||
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
|
||||
};
|
||||
unsigned int i;
|
||||
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
||||
@@ -2915,6 +2916,9 @@ static int openDatabase(
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
|
||||
| SQLITE_Fts3Tokenizer
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_QPSG)
|
||||
| SQLITE_EnableQPSG
|
||||
#endif
|
||||
;
|
||||
sqlite3HashInit(&db->aCollSeq);
|
||||
|
||||
+1
-2
@@ -1375,8 +1375,7 @@ trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z)
|
||||
}
|
||||
|
||||
%type trigger_time {int}
|
||||
trigger_time(A) ::= BEFORE. { A = TK_BEFORE; }
|
||||
trigger_time(A) ::= AFTER. { A = TK_AFTER; }
|
||||
trigger_time(A) ::= BEFORE|AFTER(X). { A = @X; /*A-overwrites-X*/ }
|
||||
trigger_time(A) ::= INSTEAD OF. { A = TK_INSTEAD;}
|
||||
trigger_time(A) ::= . { A = TK_BEFORE; }
|
||||
|
||||
|
||||
+2
-2
@@ -458,7 +458,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_ReadUncommitted },
|
||||
/* iArg: */ SQLITE_ReadUncommit },
|
||||
{/* zName: */ "recursive_triggers",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
|
||||
@@ -610,7 +610,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
/* iArg: */ SQLITE_WriteSchema },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 60 on by default, 74 total. */
|
||||
|
||||
+4
-4
@@ -25,7 +25,7 @@ static void corruptSchema(
|
||||
const char *zExtra /* Error information */
|
||||
){
|
||||
sqlite3 *db = pData->db;
|
||||
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
|
||||
if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){
|
||||
char *z;
|
||||
if( zObj==0 ) zObj = "?";
|
||||
z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
|
||||
@@ -312,8 +312,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
}
|
||||
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
|
||||
/* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
|
||||
if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
|
||||
/* Black magic: If the SQLITE_WriteSchema flag is set, then consider
|
||||
** the schema loaded, even if errors occurred. In this situation the
|
||||
** current sqlite3_prepare() operation will fail, but the following one
|
||||
** will attempt to compile the supplied statement against whatever subset
|
||||
@@ -561,7 +561,7 @@ static int sqlite3Prepare(
|
||||
if( rc ){
|
||||
const char *zDb = db->aDb[i].zDbSName;
|
||||
sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
|
||||
testcase( db->flags & SQLITE_ReadUncommitted );
|
||||
testcase( db->flags & SQLITE_ReadUncommit );
|
||||
goto end_prepare;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -910,7 +910,7 @@ static int resolveOrderByTermToExprList(
|
||||
** result-set entry.
|
||||
*/
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
|
||||
if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
@@ -1144,7 +1144,7 @@ static int resolveOrderGroupBy(
|
||||
return 1;
|
||||
}
|
||||
for(j=0; j<pSelect->pEList->nExpr; j++){
|
||||
if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
|
||||
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
|
||||
pItem->u.x.iOrderByCol = j+1;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -5005,7 +5005,9 @@ static struct SrcList_item *isSelfJoinView(
|
||||
if( pItem->zName==0 ) continue;
|
||||
if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
|
||||
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
|
||||
if( sqlite3ExprCompare(pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) ){
|
||||
if( sqlite3ExprCompare(0,
|
||||
pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1)
|
||||
){
|
||||
/* The view was modified by some other optimization such as
|
||||
** pushDownWhereTerms() */
|
||||
continue;
|
||||
|
||||
+17
@@ -3822,6 +3822,7 @@ struct ImportCtx {
|
||||
int n; /* Number of bytes in z */
|
||||
int nAlloc; /* Space allocated for z[] */
|
||||
int nLine; /* Current line number */
|
||||
int bNotFirst; /* True if one or more bytes already read */
|
||||
int cTerm; /* Character that terminated the most recent field */
|
||||
int cColSep; /* The column separator character. (Usually ",") */
|
||||
int cRowSep; /* The row separator character. (Usually "\n") */
|
||||
@@ -3901,6 +3902,21 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
|
||||
pc = c;
|
||||
}
|
||||
}else{
|
||||
/* If this is the first field being parsed and it begins with the
|
||||
** UTF-8 BOM (0xEF BB BF) then skip the BOM */
|
||||
if( (c&0xff)==0xef && p->bNotFirst==0 ){
|
||||
import_append_char(p, c);
|
||||
c = fgetc(p->in);
|
||||
if( (c&0xff)==0xbb ){
|
||||
import_append_char(p, c);
|
||||
c = fgetc(p->in);
|
||||
if( (c&0xff)==0xbf ){
|
||||
p->bNotFirst = 1;
|
||||
p->n = 0;
|
||||
return csv_read_one_field(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
while( c!=EOF && c!=cSep && c!=rSep ){
|
||||
import_append_char(p, c);
|
||||
c = fgetc(p->in);
|
||||
@@ -3912,6 +3928,7 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
|
||||
p->cTerm = c;
|
||||
}
|
||||
if( p->z ) p->z[p->n] = 0;
|
||||
p->bNotFirst = 1;
|
||||
return p->z;
|
||||
}
|
||||
|
||||
|
||||
@@ -2007,6 +2007,17 @@ struct sqlite3_mem_methods {
|
||||
** have been disabled - 0 if they are not disabled, 1 if they are.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
|
||||
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
|
||||
** a single SQL query statement will always use the same algorithm regardless
|
||||
** of values of [bound parameters]. The QPSG disables some query optimizations
|
||||
** that look at the values of bound parameters, which can make some queries
|
||||
** slower. But the QPSG has the advantage of more predictable behavior. With
|
||||
** the QPSG active, SQLite will always use the same query plan in the field as
|
||||
** was used during testing in the lab.
|
||||
** </dd>
|
||||
**
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
||||
@@ -2016,6 +2027,7 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
|
||||
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+32
-27
@@ -1450,8 +1450,8 @@ struct sqlite3 {
|
||||
** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
|
||||
** SQLITE_CacheSpill == PAGER_CACHE_SPILL
|
||||
*/
|
||||
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
|
||||
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
|
||||
#define SQLITE_WriteSchema 0x00000001 /* OK to update SQLITE_MASTER */
|
||||
#define SQLITE_LegacyFileFmt 0x00000002 /* Create new databases in format 1 */
|
||||
#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
|
||||
#define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */
|
||||
#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */
|
||||
@@ -1462,29 +1462,34 @@ struct sqlite3 {
|
||||
/* the count using a callback. */
|
||||
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
|
||||
/* result set is empty */
|
||||
#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
|
||||
#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
|
||||
#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
|
||||
#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */
|
||||
#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
|
||||
#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */
|
||||
#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */
|
||||
#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */
|
||||
#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */
|
||||
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
|
||||
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
|
||||
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
|
||||
#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */
|
||||
#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */
|
||||
#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
|
||||
#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
|
||||
#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
|
||||
#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
|
||||
#define SQLITE_NoCkptOnClose 0x80000000 /* No checkpoint on close()/DETACH */
|
||||
#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */
|
||||
#define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */
|
||||
#define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */
|
||||
#define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */
|
||||
#define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */
|
||||
#define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */
|
||||
#define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */
|
||||
#define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */
|
||||
#define SQLITE_EnableTrigger 0x00020000 /* True to enable triggers */
|
||||
#define SQLITE_DeferFKs 0x00040000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x00080000 /* Disable database changes */
|
||||
#define SQLITE_CellSizeCk 0x00100000 /* Check btree cell sizes on load */
|
||||
#define SQLITE_Fts3Tokenizer 0x00200000 /* Enable fts3_tokenizer(2) */
|
||||
#define SQLITE_EnableQPSG 0x00400000 /* Query Planner Stability Guarantee */
|
||||
/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and
|
||||
** could be factored out into a separate bit vector of the sqlite3 object. */
|
||||
#define SQLITE_InternChanges 0x00800000 /* Uncommitted Hash table changes */
|
||||
#define SQLITE_LoadExtFunc 0x01000000 /* Enable load_extension() SQL func */
|
||||
#define SQLITE_PreferBuiltin 0x02000000 /* Preference to built-in funcs */
|
||||
#define SQLITE_Vacuum 0x04000000 /* Currently in a VACUUM */
|
||||
/* Flags used only if debugging */
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
|
||||
#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -3781,10 +3786,10 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
|
||||
void sqlite3Vacuum(Parse*,Token*);
|
||||
int sqlite3RunVacuum(char**, sqlite3*, int);
|
||||
char *sqlite3NameFromToken(sqlite3*, Token*);
|
||||
int sqlite3ExprCompare(Expr*, Expr*, int);
|
||||
int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
|
||||
int sqlite3ExprCompareSkip(Expr*, Expr*, int);
|
||||
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
|
||||
int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
|
||||
int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
|
||||
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
||||
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
|
||||
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
|
||||
|
||||
+27
-26
@@ -164,18 +164,11 @@ struct SqliteDb {
|
||||
int nVMStep; /* Another statistic for most recent operation */
|
||||
int nTransaction; /* Number of nested [transaction] methods */
|
||||
int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
|
||||
unsigned int modeFlags; /* Operating mode flags */
|
||||
#ifdef SQLITE_TEST
|
||||
int bLegacyPrepare; /* True to use sqlite3_prepare() */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** Valid values for SqliteDb.modeFlags
|
||||
*/
|
||||
#define SQLITE_TCLMODE_UNSETNULL 0x0001 /* Unset NULL array values in */
|
||||
/* db eval ARRAY SQL */
|
||||
|
||||
struct IncrblobChannel {
|
||||
sqlite3_blob *pBlob; /* sqlite3 blob handle */
|
||||
SqliteDb *pDb; /* Associated database connection */
|
||||
@@ -1458,10 +1451,13 @@ struct DbEvalContext {
|
||||
const char *zSql; /* Remaining SQL to execute */
|
||||
SqlPreparedStmt *pPreStmt; /* Current statement */
|
||||
int nCol; /* Number of columns returned by pStmt */
|
||||
int evalFlags; /* Flags used */
|
||||
Tcl_Obj *pArray; /* Name of array variable */
|
||||
Tcl_Obj **apColName; /* Array of column names */
|
||||
};
|
||||
|
||||
#define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */
|
||||
|
||||
/*
|
||||
** Release any cache of column names currently held as part of
|
||||
** the DbEvalContext structure passed as the first argument.
|
||||
@@ -1494,7 +1490,8 @@ static void dbEvalInit(
|
||||
DbEvalContext *p, /* Pointer to structure to initialize */
|
||||
SqliteDb *pDb, /* Database handle */
|
||||
Tcl_Obj *pSql, /* Object containing SQL script */
|
||||
Tcl_Obj *pArray /* Name of Tcl array to set (*) element of */
|
||||
Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */
|
||||
int evalFlags /* Flags controlling evaluation */
|
||||
){
|
||||
memset(p, 0, sizeof(DbEvalContext));
|
||||
p->pDb = pDb;
|
||||
@@ -1505,6 +1502,7 @@ static void dbEvalInit(
|
||||
p->pArray = pArray;
|
||||
Tcl_IncrRefCount(pArray);
|
||||
}
|
||||
p->evalFlags = evalFlags;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1739,7 +1737,7 @@ static int SQLITE_TCLAPI DbEvalNextCmd(
|
||||
for(i=0; i<nCol; i++){
|
||||
if( pArray==0 ){
|
||||
Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
|
||||
}else if( (p->pDb->modeFlags & SQLITE_TCLMODE_UNSETNULL)!=0
|
||||
}else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
|
||||
&& sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL
|
||||
){
|
||||
Tcl_UnsetVar2(interp, Tcl_GetString(pArray),
|
||||
@@ -2458,7 +2456,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0);
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0, 0);
|
||||
rc = dbEvalStep(&sEval);
|
||||
if( choice==DB_ONECOLUMN ){
|
||||
if( rc==TCL_OK ){
|
||||
@@ -2479,7 +2477,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** $db eval $sql ?array? ?{ ...code... }?
|
||||
** $db eval ?options? $sql ?array? ?{ ...code... }?
|
||||
**
|
||||
** The SQL statement in $sql is evaluated. For each row, the values are
|
||||
** placed in elements of the array named "array" and ...code... is executed.
|
||||
@@ -2488,8 +2486,22 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
** that have the same name as the fields extracted by the query.
|
||||
*/
|
||||
case DB_EVAL: {
|
||||
int evalFlags = 0;
|
||||
const char *zOpt;
|
||||
while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
|
||||
if( strcmp(zOpt, "-withoutnulls")==0 ){
|
||||
evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
|
||||
}
|
||||
else{
|
||||
Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objc--;
|
||||
objv++;
|
||||
}
|
||||
if( objc<3 || objc>5 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
|
||||
Tcl_WrongNumArgs(interp, 2, objv,
|
||||
"?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2497,7 +2509,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
DbEvalContext sEval;
|
||||
Tcl_Obj *pRet = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pRet);
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0);
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0, 0);
|
||||
while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
|
||||
int i;
|
||||
int nCol;
|
||||
@@ -2518,14 +2530,14 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
Tcl_Obj *pArray = 0;
|
||||
Tcl_Obj *pScript;
|
||||
|
||||
if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
|
||||
if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
|
||||
pArray = objv[3];
|
||||
}
|
||||
pScript = objv[objc-1];
|
||||
Tcl_IncrRefCount(pScript);
|
||||
|
||||
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
||||
dbEvalInit(p, pDb, objv[2], pArray);
|
||||
dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
|
||||
|
||||
cd2[0] = (void *)p;
|
||||
cd2[1] = (void *)pScript;
|
||||
@@ -3320,7 +3332,6 @@ static int SQLITE_TCLAPI DbMain(
|
||||
const char *zFile;
|
||||
const char *zVfs = 0;
|
||||
int flags;
|
||||
unsigned int modeFlags = 0;
|
||||
Tcl_DString translatedFilename;
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
|
||||
void *pKey = 0;
|
||||
@@ -3411,14 +3422,6 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}else{
|
||||
flags &= ~SQLITE_OPEN_URI;
|
||||
}
|
||||
}else if( strcmp(zArg, "-unsetnull")==0 ){
|
||||
int b;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
|
||||
if( b ){
|
||||
modeFlags |= SQLITE_TCLMODE_UNSETNULL;
|
||||
}else{
|
||||
modeFlags &= ~SQLITE_TCLMODE_UNSETNULL;
|
||||
}
|
||||
}else{
|
||||
Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
|
||||
return TCL_ERROR;
|
||||
@@ -3428,7 +3431,6 @@ static int SQLITE_TCLAPI DbMain(
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
|
||||
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
" ?-unsetnull BOOLEAN?"
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
|
||||
" ?-key CODECKEY?"
|
||||
#endif
|
||||
@@ -3464,7 +3466,6 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}
|
||||
p->maxStmt = NUM_PREPARED_STMTS;
|
||||
p->openFlags = flags & SQLITE_OPEN_URI;
|
||||
p->modeFlags = modeFlags;
|
||||
p->interp = interp;
|
||||
zArg = Tcl_GetStringFromObj(objv[1], 0);
|
||||
if( DbUseNre() ){
|
||||
|
||||
@@ -7317,6 +7317,7 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
|
||||
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
{ "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||
{ "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
|
||||
{ "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG },
|
||||
};
|
||||
int i;
|
||||
int v;
|
||||
|
||||
+1
-1
@@ -6571,7 +6571,7 @@ case OP_Expire: {
|
||||
*/
|
||||
case OP_TableLock: {
|
||||
u8 isWriteLock = (u8)pOp->p3;
|
||||
if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
|
||||
if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){
|
||||
int p1 = pOp->p1;
|
||||
assert( p1>=0 && p1<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, p1) );
|
||||
|
||||
@@ -4542,6 +4542,7 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
|
||||
assert( iVar>0 );
|
||||
if( v ){
|
||||
Mem *pMem = &v->aVar[iVar-1];
|
||||
assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
|
||||
if( 0==(pMem->flags & MEM_Null) ){
|
||||
sqlite3_value *pRet = sqlite3ValueNew(v->db);
|
||||
if( pRet ){
|
||||
@@ -4561,6 +4562,7 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
|
||||
*/
|
||||
void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
|
||||
assert( iVar>0 );
|
||||
assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
|
||||
if( iVar>=32 ){
|
||||
v->expmask |= 0x80000000;
|
||||
}else{
|
||||
|
||||
+3
-6
@@ -1482,14 +1482,13 @@ static int stat4ValueFromExpr(
|
||||
/* Skip over any TK_COLLATE nodes */
|
||||
pExpr = sqlite3ExprSkipCollate(pExpr);
|
||||
|
||||
assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE );
|
||||
if( !pExpr ){
|
||||
pVal = valueNew(db, pAlloc);
|
||||
if( pVal ){
|
||||
sqlite3VdbeMemSetNull((Mem*)pVal);
|
||||
}
|
||||
}else if( pExpr->op==TK_VARIABLE
|
||||
|| NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
|
||||
){
|
||||
}else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
|
||||
Vdbe *v;
|
||||
int iBindVar = pExpr->iColumn;
|
||||
sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
|
||||
@@ -1497,9 +1496,7 @@ static int stat4ValueFromExpr(
|
||||
pVal = valueNew(db, pAlloc);
|
||||
if( pVal ){
|
||||
rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
|
||||
}
|
||||
sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
|
||||
pVal->db = pParse->db;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -2654,7 +2654,7 @@ static int indexMightHelpWithOrderBy(
|
||||
}else if( (aColExpr = pIndex->aColExpr)!=0 ){
|
||||
for(jj=0; jj<pIndex->nKeyCol; jj++){
|
||||
if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
|
||||
if( sqlite3ExprCompare(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
|
||||
if( sqlite3ExprCompare(0, pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -2687,14 +2687,16 @@ static Bitmask columnsInIndex(Index *pIdx){
|
||||
static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
int i;
|
||||
WhereTerm *pTerm;
|
||||
Parse *pParse = pWC->pWInfo->pParse;
|
||||
while( pWhere->op==TK_AND ){
|
||||
if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0;
|
||||
pWhere = pWhere->pRight;
|
||||
}
|
||||
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
|
||||
&& (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
@@ -3673,7 +3675,8 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
if( pOBExpr->iTable!=iCur ) continue;
|
||||
if( pOBExpr->iColumn!=iColumn ) continue;
|
||||
}else{
|
||||
if( sqlite3ExprCompare(pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
|
||||
if( sqlite3ExprCompare(0,
|
||||
pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1058,7 +1058,7 @@ typedef struct IdxExprTrans {
|
||||
*/
|
||||
static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
|
||||
IdxExprTrans *pX = p->u.pIdxTrans;
|
||||
if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
|
||||
if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
|
||||
pExpr->op = TK_COLUMN;
|
||||
pExpr->iTable = pX->iIdxCur;
|
||||
pExpr->iColumn = pX->iIdxCol;
|
||||
|
||||
+6
-3
@@ -216,7 +216,7 @@ static int isLikeOrGlob(
|
||||
|
||||
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
|
||||
op = pRight->op;
|
||||
if( op==TK_VARIABLE ){
|
||||
if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
|
||||
Vdbe *pReprepare = pParse->pReprepare;
|
||||
int iCol = pRight->iColumn;
|
||||
pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
|
||||
@@ -406,8 +406,8 @@ static void whereCombineDisjuncts(
|
||||
&& (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
|
||||
assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
|
||||
assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
|
||||
if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
|
||||
if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return;
|
||||
if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
|
||||
if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return;
|
||||
/* If we reach this point, it means the two subterms can be combined */
|
||||
if( (eOp & (eOp-1))!=0 ){
|
||||
if( eOp & (WO_LT|WO_LE) ){
|
||||
@@ -1178,6 +1178,9 @@ static void exprAnalyze(
|
||||
Expr *pNewExpr;
|
||||
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
|
||||
0, sqlite3ExprDup(db, pRight, 0));
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
|
||||
ExprSetProperty(pNewExpr, EP_FromJoin);
|
||||
}
|
||||
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
testcase( idxNew==0 );
|
||||
pNewTerm = &pWC->a[idxNew];
|
||||
|
||||
@@ -123,6 +123,36 @@ do_eqp_test analyze3-1.1.3 {
|
||||
SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
|
||||
# 2017-06-26: Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
|
||||
# the use of bound parameters by STAT4
|
||||
#
|
||||
db cache flush
|
||||
unset -nocomplain l
|
||||
unset -nocomplain u
|
||||
do_eqp_test analyze3-1.1.3.100 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
set l 200
|
||||
set u 300
|
||||
do_eqp_test analyze3-1.1.3.101 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
set l 0
|
||||
set u 1100
|
||||
do_eqp_test analyze3-1.1.3.102 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
db cache flush
|
||||
sqlite3_db_config db ENABLE_QPSG 1
|
||||
do_eqp_test analyze3-1.1.3.103 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
|
||||
db cache flush
|
||||
sqlite3_db_config db ENABLE_QPSG 0
|
||||
do_eqp_test analyze3-1.1.3.104 {
|
||||
SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
|
||||
} {0 0 0 {SCAN TABLE t1}}
|
||||
|
||||
do_test analyze3-1.1.4 {
|
||||
sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
|
||||
} {199 0 14850}
|
||||
|
||||
@@ -61,4 +61,24 @@ do_catchsql_test 2.5 {
|
||||
SELECT * FROM ft3, ft2 WHERE y MATCH x AND x MATCH y;
|
||||
} {1 {unable to use function MATCH in the requested context}}
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE vt USING fts3(x);
|
||||
INSERT INTO vt VALUES('abc');
|
||||
INSERT INTO vt VALUES('xyz');
|
||||
|
||||
CREATE TABLE tt(a INTEGER PRIMARY KEY);
|
||||
INSERT INTO tt VALUES(1), (2);
|
||||
}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
SELECT * FROM tt LEFT JOIN (
|
||||
SELECT rowid AS rrr, * FROM vt WHERE vt MATCH 'abc'
|
||||
) ON tt.a = rrr
|
||||
} {1 1 abc 2 {} {}}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
SELECT * FROM tt LEFT JOIN vt ON (vt MATCH 'abc')
|
||||
} {1 abc 2 abc}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# 2017 Jun 24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test that partial indexes work with bound variables.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix index9
|
||||
|
||||
proc sqluses {sql} {
|
||||
array unset ::T
|
||||
uplevel [list db eval "EXPLAIN $sql" a {
|
||||
if {$a(opcode)=="OpenRead"} { set ::T($a(p2)) 1 }
|
||||
}]
|
||||
|
||||
set in [join [array names ::T] ,]
|
||||
db eval "SELECT name FROM sqlite_master WHERE rootpage IN ($in) ORDER BY 1"
|
||||
}
|
||||
|
||||
proc do_sqluses_test {tn sql objects} {
|
||||
uplevel [list do_test $tn [list sqluses $sql] $objects]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE INDEX t1x ON t1(x) WHERE y=45;
|
||||
}
|
||||
set y [expr 45]
|
||||
do_sqluses_test 1.1 { SELECT * FROM t1 WHERE x=? AND y=$y } {t1 t1x}
|
||||
set y [expr 45.1]
|
||||
do_sqluses_test 1.2 { SELECT * FROM t1 WHERE x=? AND y=$y } {t1}
|
||||
set y [expr 44]
|
||||
do_sqluses_test 1.3 { SELECT * FROM t1 WHERE x=? AND y=$y } {t1}
|
||||
unset -nocomplain y
|
||||
do_sqluses_test 1.4 { SELECT * FROM t1 WHERE x=? AND y=$y } {t1}
|
||||
set y [string range "45" 0 end]
|
||||
do_sqluses_test 1.5 { SELECT * FROM t1 WHERE x=? AND y=$y } {t1}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE INDEX t1x2 ON t1(x) WHERE y=-20111000111
|
||||
}
|
||||
do_sqluses_test 2.1 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
set y [expr -20111000111]
|
||||
do_sqluses_test 2.2 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1 t1x2}
|
||||
set y [expr -20111000110]
|
||||
do_sqluses_test 2.3 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
set y [expr -20111000112]
|
||||
do_sqluses_test 2.4 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE INDEX t1x3 ON t1(x) WHERE y=9223372036854775807
|
||||
}
|
||||
set y [expr 9223372036854775807]
|
||||
do_sqluses_test 3.1 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1 t1x3}
|
||||
set y [expr 9223372036854775808]
|
||||
do_sqluses_test 3.2 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
set y [expr 9223372036854775806]
|
||||
do_sqluses_test 3.3 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
db cache flush
|
||||
sqlite3_db_config db QPSG 1
|
||||
set y [expr 9223372036854775807]
|
||||
do_sqluses_test 3.4 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
set y [expr 9223372036854775808]
|
||||
do_sqluses_test 3.5 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
sqlite3_db_config db QPSG 0
|
||||
db cache flush
|
||||
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
CREATE INDEX t1x4 ON t1(x) WHERE y=-9223372036854775808
|
||||
}
|
||||
set y [expr -9223372036854775808]
|
||||
do_sqluses_test 4.1 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1 t1x4}
|
||||
set y [expr -9223372036854775807]
|
||||
do_sqluses_test 4.2 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
set y [expr -9223372036854775809]
|
||||
do_sqluses_test 4.3 { SELECT * FROM t1 WHERE y=$y ORDER BY x } {t1}
|
||||
set y [expr -9223372036854775808]
|
||||
do_sqluses_test 4.4 { SELECT * FROM t1 WHERE $y=y ORDER BY x } {t1 t1x4}
|
||||
db cache flush
|
||||
sqlite3_db_config db QPSG 1
|
||||
do_sqluses_test 4.5 { SELECT * FROM t1 WHERE $y=y ORDER BY x } {t1}
|
||||
sqlite3_db_config db QPSG 0
|
||||
db cache flush
|
||||
|
||||
finish_test
|
||||
+44
-2
@@ -160,6 +160,7 @@ ifcapable !like_opt {
|
||||
#
|
||||
proc queryplan {sql} {
|
||||
set ::sqlite_sort_count 0
|
||||
db cache flush
|
||||
set data [execsql $sql]
|
||||
if {$::sqlite_sort_count} {set x sort} {set x nosort}
|
||||
lappend data $x
|
||||
@@ -196,7 +197,7 @@ do_test like-3.2 {
|
||||
|
||||
# With an index on t1.x and case sensitivity on, optimize completely.
|
||||
#
|
||||
do_test like-3.3 {
|
||||
do_test like-3.3.100 {
|
||||
set sqlite_like_count 0
|
||||
execsql {
|
||||
PRAGMA case_sensitive_like=on;
|
||||
@@ -206,10 +207,51 @@ do_test like-3.3 {
|
||||
SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
|
||||
}
|
||||
} {abc abcd nosort {} i1}
|
||||
do_test like-3.4 {
|
||||
do_test like-3.3.101 {
|
||||
set sqlite_like_count
|
||||
} 0
|
||||
|
||||
# The like optimization works even when the pattern is a bound parameter
|
||||
#
|
||||
do_test like-3.3.102 {
|
||||
set sqlite_like_count 0
|
||||
unset -nocomplain ::likepat
|
||||
set ::likepat abc%
|
||||
queryplan {
|
||||
SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
|
||||
}
|
||||
} {abc abcd nosort {} i1}
|
||||
do_test like-3.3.103 {
|
||||
set sqlite_like_count
|
||||
} 0
|
||||
|
||||
# Except, the like optimization does not work for bound parameters if
|
||||
# the query planner stability guarantee is active.
|
||||
#
|
||||
do_test like-3.3.104 {
|
||||
set sqlite_like_count 0
|
||||
sqlite3_db_config db QPSG 1
|
||||
queryplan {
|
||||
SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
|
||||
}
|
||||
} {abc abcd nosort {} i1}
|
||||
do_test like-3.3.105 {
|
||||
set sqlite_like_count
|
||||
} 12
|
||||
|
||||
# The query planner stability guarantee does not disrupt explicit patterns
|
||||
#
|
||||
do_test like-3.3.105 {
|
||||
set sqlite_like_count 0
|
||||
queryplan {
|
||||
SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
|
||||
}
|
||||
} {abc abcd nosort {} i1}
|
||||
do_test like-3.3.106 {
|
||||
set sqlite_like_count
|
||||
} 0
|
||||
sqlite3_db_config db QPSG 0
|
||||
|
||||
# The LIKE optimization still works when the RHS is a string with no
|
||||
# wildcard. Ticket [e090183531fc2747]
|
||||
#
|
||||
|
||||
+32
-1
@@ -184,6 +184,36 @@ do_test shell5-1.4.10.2 {
|
||||
catchcmd "test.db" {SELECT b FROM t1 WHERE a='7';}
|
||||
} {0 {Now is the time for all good men to come to the aid of their country.}}
|
||||
|
||||
# import file with 2 rows, 2 columns and an initial BOM
|
||||
#
|
||||
do_test shell5-1.4.11 {
|
||||
set in [open shell5.csv wb]
|
||||
puts $in "\xef\xbb\xbf2|3"
|
||||
puts $in "4|5"
|
||||
close $in
|
||||
set res [catchcmd "test.db" {CREATE TABLE t2(x INT, y INT);
|
||||
.import shell5.csv t2
|
||||
.mode quote
|
||||
.header on
|
||||
SELECT * FROM t2;}]
|
||||
string map {\n | \n\r |} $res
|
||||
} {0 {'x','y'|2,3|4,5}}
|
||||
|
||||
# import file with 2 rows, 2 columns or text with an initial BOM
|
||||
#
|
||||
do_test shell5-1.4.12 {
|
||||
set in [open shell5.csv wb]
|
||||
puts $in "\xef\xbb\xbf\"two\"|3"
|
||||
puts $in "4|5"
|
||||
close $in
|
||||
set res [catchcmd "test.db" {DELETE FROM t2;
|
||||
.import shell5.csv t2
|
||||
.mode quote
|
||||
.header on
|
||||
SELECT * FROM t2;}]
|
||||
string map {\n | \n\r |} $res
|
||||
} {0 {'x','y'|'two',3|4,5}}
|
||||
|
||||
# check importing very long field
|
||||
do_test shell5-1.5.1 {
|
||||
set str [string repeat X 999]
|
||||
@@ -210,7 +240,8 @@ do_test shell5-1.6.1 {
|
||||
set in [open shell5.csv w]
|
||||
puts $in $data
|
||||
close $in
|
||||
set res [catchcmd "test.db" {.import shell5.csv t2
|
||||
set res [catchcmd "test.db" {DROP TABLE IF EXISTS t2;
|
||||
.import shell5.csv t2
|
||||
SELECT COUNT(*) FROM t2;}]
|
||||
} {0 1}
|
||||
|
||||
|
||||
+20
-17
@@ -22,7 +22,7 @@ source $testdir/tester.tcl
|
||||
|
||||
# Check the error messages generated by tclsqlite
|
||||
#
|
||||
set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN? ?-unsetnull BOOLEAN?"
|
||||
set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
if {[sqlite3 -has-codec]} {
|
||||
append r " ?-key CODECKEY?"
|
||||
}
|
||||
@@ -113,7 +113,7 @@ ifcapable {complete} {
|
||||
do_test tcl-1.14 {
|
||||
set v [catch {db eval} msg]
|
||||
lappend v $msg
|
||||
} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
|
||||
} {1 {wrong # args: should be "db eval ?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"}}
|
||||
do_test tcl-1.15 {
|
||||
set v [catch {db function} msg]
|
||||
lappend v $msg
|
||||
@@ -664,12 +664,13 @@ do_test tcl-15.5 {
|
||||
db exists {SELECT a FROM t1 WHERE a>3}
|
||||
} {0}
|
||||
|
||||
# 2017-06-26: Different behavior with "-unsetnull 1" versus "-unsetnull 0"
|
||||
|
||||
# 2017-06-26: The --withoutnulls flag to "db eval".
|
||||
#
|
||||
# In the "db eval SQL ARRAY" form, NULL results cause the corresponding
|
||||
# array entry to be unset with -unsetnull 1. With -unsetnull 0, the NULL
|
||||
# results cause the array entry to be filled with the [db nullvalue] string.
|
||||
# The -unsetnull 0 version is the default, for legacy compatibility.
|
||||
# In the "db eval --withoutnulls SQL ARRAY" form, NULL results cause the
|
||||
# corresponding array entry to be unset. The default behavior (without
|
||||
# the -withoutnulls flags) is for the corresponding array value to get
|
||||
# the [db nullvalue] string.
|
||||
#
|
||||
catch {db close}
|
||||
forcedelete test.db
|
||||
@@ -686,23 +687,25 @@ do_test tcl-16.101 {
|
||||
}
|
||||
set res
|
||||
} {1 {a b *} 2 {a b *} 3 {a b *}}
|
||||
sqlite3 db test.db -unsetnull 0
|
||||
do_test tcl-16.102 {
|
||||
set res {}
|
||||
unset -nocomplain x
|
||||
db eval {SELECT * FROM t1} x {
|
||||
lappend res $x(a) [array names x]
|
||||
}
|
||||
set res
|
||||
} {1 {a b *} 2 {a b *} 3 {a b *}}
|
||||
sqlite3 db test.db -unsetnull 1
|
||||
set res [catch {
|
||||
db eval -unknown {SELECT * FROM t1} x {
|
||||
lappend res $x(a) [array names x]
|
||||
}
|
||||
} rc]
|
||||
lappend res $rc
|
||||
} {1 {unknown option: "-unknown"}}
|
||||
do_test tcl-16.103 {
|
||||
set res {}
|
||||
unset -nocomplain x
|
||||
db eval {SELECT * FROM t1} x {
|
||||
db eval -withoutnulls {SELECT * FROM t1} x {
|
||||
lappend res $x(a) [array names x]
|
||||
}
|
||||
set res
|
||||
} {1 {a b *} 2 {a *} 3 {a b *}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+9
-2
@@ -3297,7 +3297,14 @@ PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
|
||||
int act;
|
||||
switch( ap->type ){
|
||||
case SHIFT: act = ap->x.stp->statenum; break;
|
||||
case SHIFTREDUCE: act = ap->x.rp->iRule + lemp->nstate; break;
|
||||
case SHIFTREDUCE: {
|
||||
act = ap->x.rp->iRule + lemp->nstate;
|
||||
/* Since a SHIFT is inherient after a prior REDUCE, convert any
|
||||
** SHIFTREDUCE action with a nonterminal on the LHS into a simple
|
||||
** REDUCE action: */
|
||||
if( ap->sp->index>=lemp->nterminal ) act += lemp->nrule;
|
||||
break;
|
||||
}
|
||||
case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break;
|
||||
case ERROR: act = lemp->nstate + lemp->nrule*2; break;
|
||||
case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break;
|
||||
@@ -4415,7 +4422,7 @@ void ReportTable(
|
||||
** sequentually beginning with 0.
|
||||
*/
|
||||
for(rp=lemp->rule; rp; rp=rp->next){
|
||||
fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++;
|
||||
fprintf(out," { %d, %d },\n",rp->lhs->index,-rp->nrhs); lineno++;
|
||||
}
|
||||
tplt_xfer(lemp->name,in,out,&lineno);
|
||||
|
||||
|
||||
+21
-15
@@ -221,6 +221,7 @@ struct yyParser {
|
||||
yyStackEntry yystk0; /* First stack entry */
|
||||
#else
|
||||
yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
|
||||
yyStackEntry *yystackEnd; /* Last entry in the stack */
|
||||
#endif
|
||||
};
|
||||
typedef struct yyParser yyParser;
|
||||
@@ -338,6 +339,7 @@ void ParseInit(void *yypParser){
|
||||
pParser->yytos = pParser->yystack;
|
||||
pParser->yystack[0].stateno = 0;
|
||||
pParser->yystack[0].major = 0;
|
||||
pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1];
|
||||
}
|
||||
|
||||
#ifndef Parse_ENGINEALWAYSONSTACK
|
||||
@@ -607,7 +609,7 @@ static void yy_shift(
|
||||
}
|
||||
#endif
|
||||
#if YYSTACKDEPTH>0
|
||||
if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){
|
||||
if( yypParser->yytos>yypParser->yystackEnd ){
|
||||
yypParser->yytos--;
|
||||
yyStackOverflow(yypParser);
|
||||
return;
|
||||
@@ -635,8 +637,8 @@ static void yy_shift(
|
||||
** is used during the reduce.
|
||||
*/
|
||||
static const struct {
|
||||
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
|
||||
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
|
||||
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
|
||||
signed char nrhs; /* Negative of the number of RHS symbols in the rule */
|
||||
} yyRuleInfo[] = {
|
||||
%%
|
||||
};
|
||||
@@ -661,7 +663,7 @@ static void yy_reduce(
|
||||
if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
|
||||
yysize = yyRuleInfo[yyruleno].nrhs;
|
||||
fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
|
||||
yyRuleName[yyruleno], yymsp[-yysize].stateno);
|
||||
yyRuleName[yyruleno], yymsp[yysize].stateno);
|
||||
}
|
||||
#endif /* NDEBUG */
|
||||
|
||||
@@ -676,7 +678,7 @@ static void yy_reduce(
|
||||
}
|
||||
#endif
|
||||
#if YYSTACKDEPTH>0
|
||||
if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){
|
||||
if( yypParser->yytos>=yypParser->yystackEnd ){
|
||||
yyStackOverflow(yypParser);
|
||||
return;
|
||||
}
|
||||
@@ -707,20 +709,24 @@ static void yy_reduce(
|
||||
assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
|
||||
yygoto = yyRuleInfo[yyruleno].lhs;
|
||||
yysize = yyRuleInfo[yyruleno].nrhs;
|
||||
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
|
||||
if( yyact <= YY_MAX_SHIFTREDUCE ){
|
||||
if( yyact>YY_MAX_SHIFT ){
|
||||
yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
|
||||
}
|
||||
yymsp -= yysize-1;
|
||||
yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
|
||||
|
||||
/* There are no SHIFTREDUCE actions on nonterminals because the table
|
||||
** generator has simplified them to pure REDUCE actions. */
|
||||
assert( !(yyact>YY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) );
|
||||
|
||||
/* It is not possible for a REDUCE to be followed by an error */
|
||||
assert( yyact!=YY_ERROR_ACTION );
|
||||
|
||||
if( yyact==YY_ACCEPT_ACTION ){
|
||||
yypParser->yytos += yysize;
|
||||
yy_accept(yypParser);
|
||||
}else{
|
||||
yymsp += yysize+1;
|
||||
yypParser->yytos = yymsp;
|
||||
yymsp->stateno = (YYACTIONTYPE)yyact;
|
||||
yymsp->major = (YYCODETYPE)yygoto;
|
||||
yyTraceShift(yypParser, yyact);
|
||||
}else{
|
||||
assert( yyact == YY_ACCEPT_ACTION );
|
||||
yypParser->yytos -= yysize;
|
||||
yy_accept(yypParser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,12 +120,12 @@ set pragma_def {
|
||||
|
||||
NAME: writable_schema
|
||||
TYPE: FLAG
|
||||
ARG: SQLITE_WriteSchema|SQLITE_RecoveryMode
|
||||
ARG: SQLITE_WriteSchema
|
||||
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
|
||||
NAME: read_uncommitted
|
||||
TYPE: FLAG
|
||||
ARG: SQLITE_ReadUncommitted
|
||||
ARG: SQLITE_ReadUncommit
|
||||
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
|
||||
NAME: recursive_triggers
|
||||
|
||||
Reference in New Issue
Block a user