mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Merge all the latest trunk enhancements and fixes into the temp-trigger-refs
branch. FossilOrigin-Name: 8e8a27c77aa0ea5891968231e13a8caeade48b817419bbf6eda18ad217f1df63
This commit is contained in:
14
ext/qrf/dev-notes.md
Normal file
14
ext/qrf/dev-notes.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Developer Notes
|
||||
|
||||
## Measuring Test Coverage On Linux
|
||||
|
||||
On Mint Linux, as of 2025-12-02:
|
||||
|
||||
> ~~~
|
||||
./configure --dev CFLAGS='-O0 -g -fprofile-arcs -ftest-coverage'
|
||||
make clean testfixture
|
||||
./testfixture test/qrf*.test
|
||||
gcov -b -c testfixture-tclsqlite-ex.c
|
||||
~~~
|
||||
|
||||
View results in tclsqlite-ex.c.gcov
|
||||
@@ -537,13 +537,20 @@ static int qrfIsVt100(const unsigned char *z){
|
||||
|
||||
/*
|
||||
** Return the length of a string in display characters.
|
||||
** Multibyte UTF8 characters count as a single character
|
||||
** for single-width characters, or as two characters for
|
||||
** double-width characters.
|
||||
**
|
||||
** Most characters of the input string count as 1, including
|
||||
** multi-byte UTF8 characters. However, zero-width unicode
|
||||
** characters and VT100 escape sequences count as zero, and
|
||||
** double-width characters count as two.
|
||||
**
|
||||
** The definition of "zero-width" and "double-width" characters
|
||||
** is not precise. It depends on the output device, to some extent,
|
||||
** and it varies according to the Unicode version. This routine
|
||||
** makes the best guess that it can.
|
||||
*/
|
||||
static int qrfDisplayLength(const char *zIn){
|
||||
size_t sqlite3_qrf_wcswidth(const char *zIn){
|
||||
const unsigned char *z = (const unsigned char*)zIn;
|
||||
int n = 0;
|
||||
size_t n = 0;
|
||||
while( *z ){
|
||||
if( z[0]<' ' ){
|
||||
int k;
|
||||
@@ -2198,7 +2205,7 @@ static void qrfExplain(Qrf *p){
|
||||
int len;
|
||||
if( i==nArg-1 ) w = 0;
|
||||
if( zVal==0 ) zVal = "";
|
||||
len = qrfDisplayLength(zVal);
|
||||
len = (int)sqlite3_qrf_wcswidth(zVal);
|
||||
if( len>w ){
|
||||
w = len;
|
||||
zSep = " ";
|
||||
@@ -2388,7 +2395,7 @@ static void qrfOneSimpleRow(Qrf *p){
|
||||
int sz;
|
||||
p->u.sLine.azCol[i] = sqlite3_column_name(p->pStmt, i);
|
||||
if( p->u.sLine.azCol[i]==0 ) p->u.sLine.azCol[i] = "unknown";
|
||||
sz = qrfDisplayLength(p->u.sLine.azCol[i]);
|
||||
sz = (int)sqlite3_qrf_wcswidth(p->u.sLine.azCol[i]);
|
||||
if( sz > p->u.sLine.mxColWth ) p->u.sLine.mxColWth = sz;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,13 +176,21 @@ int sqlite3_format_query_result(
|
||||
** character c. For normal characters, the answer is always 1. But the
|
||||
** estimate might be 0 or 2 for zero-width and double-width characters.
|
||||
**
|
||||
** Different display devices display unicode using different widths. So
|
||||
** Different devices display unicode using different widths. So
|
||||
** it is impossible to know that true display width with 100% accuracy.
|
||||
** Inaccuracies in the width estimates might cause columns to be misaligned.
|
||||
** Unfortunately, there is nothing we can do about that.
|
||||
*/
|
||||
int sqlite3_qrf_wcwidth(int c);
|
||||
|
||||
/*
|
||||
** Return an estimate of the number of display columns used by the
|
||||
** string in the argument. The width of individual characters is
|
||||
** determined as for sqlite3_qrf_wcwidth(). VT100 escape code sequences
|
||||
** are assigned a width of zero.
|
||||
*/
|
||||
size_t sqlite3_qrf_wcswidth(const char*);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1107,11 +1107,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
sqlite3.config.warn("DB.exec() is propagating exception",opt,e);
|
||||
throw e;
|
||||
}*/finally{
|
||||
wasm.scopedAllocPop(stack);
|
||||
if(stmt){
|
||||
__execLock.delete(stmt);
|
||||
stmt.finalize();
|
||||
}
|
||||
wasm.scopedAllocPop(stack);
|
||||
}
|
||||
return arg.returnVal();
|
||||
}/*exec()*/,
|
||||
|
||||
47
manifest
47
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sa\smemory\sleak\sthat\scould\sfollow\san\sOOM\son\sthis\sbranch.
|
||||
D 2025-12-01T18:11:08.093
|
||||
C Merge\sall\sthe\slatest\strunk\senhancements\sand\sfixes\sinto\sthe\stemp-trigger-refs\nbranch.
|
||||
D 2025-12-04T11:20:01.398
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
@@ -417,8 +417,9 @@ F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6
|
||||
F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c
|
||||
F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
|
||||
F ext/qrf/README.md 86fc5c3c5e3eddbe54fc1235cbdc52b8c2c0732791d224345c3014cd45c4c0e7
|
||||
F ext/qrf/qrf.c 425d02cffcc5b5fe9ff5817794bf751b1fdd6912f570c354272429ce1262b866
|
||||
F ext/qrf/qrf.h 322d48537a5aa39c206c2ec0764a7938ea7662a8c25be1c4e9d742789609ba1e
|
||||
F ext/qrf/dev-notes.md e68a6d91ce4c7eb296ef2daadc2bb79c95c317ad15b9fafe40850c67b29c2430
|
||||
F ext/qrf/qrf.c c50368ea2be3ab67bd6698d8b34bf70210d3fbf6b3659ed328543e5ec8d69eff
|
||||
F ext/qrf/qrf.h 2cd7bd43579c522d3ae5c16034c7fdf41085684189811ae8e18ebc932a1cc79f
|
||||
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
|
||||
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
|
||||
F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363
|
||||
@@ -594,7 +595,7 @@ F ext/wasm/api/post-js-footer.js a50c1a2c4d008aede7b2aa1f18891a7ee71437c2f415b8a
|
||||
F ext/wasm/api/post-js-header.js d24bd0d065f3489c8b78ddf3ead6321e5d047187a162cd503c41700e03dd1f06
|
||||
F ext/wasm/api/pre-js.c-pp.js d73088472f91856a27837c0588ac355516cea441ff67d2990effc2ca0627bf21
|
||||
F ext/wasm/api/sqlite3-api-glue.c-pp.js 9b33e3ee467791dec4fd1b444b12a8545dfbb6c8b28ac651c7bdc7661a3b5a5c
|
||||
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 7a6c85b260082d72a5c355caf37876763d8770a29d9e0587751e584c31bf2777
|
||||
F ext/wasm/api/sqlite3-api-oo1.c-pp.js b2fa08dc02a0d852d88c59ce4a77cce3af033982f7eb41eeb81f1ba80f5f1b10
|
||||
F ext/wasm/api/sqlite3-api-prologue.js fd836265adefbe4ed8a978326e0273bafcfb7d42f754b69a5d131a9031428c9f
|
||||
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
@@ -668,7 +669,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 1b9c24374a85dfc7eb8fa7c4266ee0db4f9609cceecfc5481cd8307e5af04366
|
||||
F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398
|
||||
F src/alter.c 06a27ab1cc064f5c6647e7fadfb12c8d7cafd35de1751f12419e1f2b28037540
|
||||
F src/alter.c 6c7791c7d95f66df7c510ed006bd8b0a58badfd7106ad2aa97f2d10ae3c3e06d
|
||||
F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
|
||||
F src/attach.c 7cf07d4fa42b9fc8662237c60c40b730326c30aa90ae5fffc0b18b2d726ebf61
|
||||
F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
|
||||
@@ -686,7 +687,7 @@ F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
|
||||
F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
|
||||
F src/expr.c 17b0cbe08e004c1653030f5de9b6b050e84feaa112239f7f576af2dc5e53a5fb
|
||||
F src/expr.c b4530f3e23d8ea38c7de4c7b55af52d43156c79128c042a580e670776f59a9bc
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c c065da737307a29e4d240ac727758dbf4102cb3218a1f651eb689b6a6fa12531
|
||||
F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
|
||||
@@ -725,7 +726,7 @@ F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
|
||||
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
|
||||
F src/pager.c a81461de271ac4886ad75b7ca2cca8157a48635820c4646cd2714acdc2c17e5f
|
||||
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
|
||||
F src/parse.y e31046636c50ba4a1cf4d12c7a6112a31b11975b1ade84a45f2109a30e8f358d
|
||||
F src/parse.y 015375decff21fa3be5688189d58988458db8e3ccb821041b0fb7de4cd2fcf30
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
|
||||
@@ -733,18 +734,18 @@ F src/pragma.c ecec75795c1821520266e4f93fa8840cce48979af532db06f085e36a7813860f
|
||||
F src/prepare.c f6a6e28a281bd1d1da12f47d370a81af46159b40f73bf7fa0b276b664f9c8b7d
|
||||
F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
|
||||
F src/resolve.c 8d53771eb51a4ab5f970150c3a70969d8db79cd04a8774c2d296bbcf471a0dd0
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 6a509cddd815d64f6141e539fff633a518a393772a44dffb4490f7fc3f0d83a9
|
||||
F src/shell.c.in 8ec8bf61a3322c5e29c286d4aecbc82e25157df9244cb1a1a1c4e2c49de8b64d
|
||||
F src/select.c 344518c1bba9c4636bf651b7642304abd2e7075ba35feb4bae42a51e5efe991f
|
||||
F src/shell.c.in 62b286951404fd72c116bb3b96b5ee9330de4dc4c8753ca33967ca1a47b3b972
|
||||
F src/sqlite.h.in 706cacea5308b0244fb6cec92e08310fb427a125375c64137cc1f878ae4cf5c0
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998
|
||||
F src/sqliteInt.h f8b6a6bdb92aaeeedd768d27650a39f543c4b7cc66534c564e2ec249ed80e210
|
||||
F src/sqliteInt.h af67bc95fa6b66cd3c7f3d18d2d040ad386e4cbb02965ee318cc721ee9d5fa45
|
||||
F src/sqliteLimit.h 0a5516b4ec192a205c541e05f67009028a9451dc6678aae4cf8e68596903c246
|
||||
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c ec2ad3fbf5390c3d4307bc9d1f2a37a9c5d726b5309769dc770ab37f6812152d
|
||||
F src/tclsqlite.c 4b6f6b142b951a8a127e0cbd2e37284fc71f8e6a391ec8c6188fb831b51ec0b8
|
||||
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
|
||||
F src/test1.c 0e71fbcb484a271564e98e0158192c28c24f5521594218c3ba48bcb4cf634f91
|
||||
F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
|
||||
@@ -820,8 +821,8 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||
F src/where.c 1b554a868134cbc9ca2192385403c0b63e5073ff01a6cdd600a846c09f843165
|
||||
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
|
||||
F src/wherecode.c 71c5c6804b7f882dec8ec858758accae02fcfca13df3cc720f1f258e663ec7c5
|
||||
F src/whereexpr.c 403a44eeec1a0f0914fccc6a59376b6924bc00ef6728fe6ffce4cf3051b320fc
|
||||
F src/window.c 538195bbc75bb924e18e368fbd4ed731a3fe3f901351b44f6466ec486f53affe
|
||||
F src/whereexpr.c 5f412da6616e26b8000dd736a5ce5da0018dff0933cd656bbb25f407db16bf93
|
||||
F src/window.c c0a38cd32473e8e8e7bc435039f914a36ca42465506dc491c65870c01ddac9fb
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
|
||||
F test/affinity3.test 9b7d1133e11d5edd7805573c4ab6f3ba73b0b74a1f280d5b130d4bf3506a93ff
|
||||
@@ -851,7 +852,7 @@ F test/altermalloc3.test 8040e486368403f2fdd6fc3998258b499bd4cc2f3ddbb5f8f874cd4
|
||||
F test/alterqf.test 8ec03d776de9c391daa0078ea8f838903bdcfb11dfae4ba3576b48436834ccba
|
||||
F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586a7a27
|
||||
F test/altertab2.test 0889ba0700cc1cdb7bc7d25975aa61fece34f621de963d0886e2395716b38576
|
||||
F test/altertab3.test 471b8898d10bbc6488db9c23dc76811f405de6707d2d342b1b8b6fd1f13cd3c8
|
||||
F test/altertab3.test 575e771e2f02b13eb98798dc92eabacd187d6dbcf596e70f11d699b0b6b5d0b2
|
||||
F test/altertrig.test b1590647076add5a47aea0f2236c609ca0bc8a7a2462463edd3e5882c7894802
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b
|
||||
@@ -1514,6 +1515,8 @@ F test/qrf01.test 48c86e90f606739e67b73937babb662ef0edf1ede06954489c588815fa17b5
|
||||
F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92
|
||||
F test/qrf03.test ad7fa339fb46b26b08625f3a77a4827bdee9f0dad402d8ddc1fcb8f05aa64a54
|
||||
F test/qrf04.test 0894692c998d2401dcc33449c02051b503ecce0c94217be54fb007c82d2d1379
|
||||
F test/qrf05.test 8ade5bfa7ef0b448e531687203fa8ae9ef41f1d7e4c11d5ba0c4846af75b13d5
|
||||
F test/qrf06.test 3907f81c79fd884802cc7552d4a07fd8d73c381ade9d5108e6d7f56fd962b99b
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a
|
||||
@@ -1607,7 +1610,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
|
||||
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test f377091779c4099619e78e1f55a0a12513eaac55d5073a14ca6545c6742c746c
|
||||
F test/shell1.test b49a89913c194c37ca10c9ded1b6b6866506104621c6cc599e557e4cb5ed8cc2
|
||||
F test/shell2.test 103140814bdc7508aa41dd3462413cbc4aa84b4261112cb8d501d74275cb7d48
|
||||
F test/shell3.test 840192774cc4edf7653520c0434a311c7477b9bc324abbc7bd2887915792fa8c
|
||||
F test/shell4.test e25580a792b7b54560c3a76b6968bd8189261f38979fe28e6bc6312c5db280db
|
||||
@@ -1672,7 +1675,7 @@ F test/strict1.test a7f9091603fe71cdc62baab0766684cba12a97ec69bfbb70be965532669c
|
||||
F test/strict2.test b22c7a98b5000aef937f1990776497f0e979b1a23bc4f63e2d53b00e59b20070
|
||||
F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49
|
||||
F test/subquery.test 23087f9b1c15ab9cc5231d04946bdebc51db527c95eb9d7434a2222127e17a84
|
||||
F test/subquery2.test 5f06ec2dbce42a3f595ab1b73b146592f9ce001cd4ff023d887d643d3560c281
|
||||
F test/subquery2.test ab96ff3fa9c4e3dce0d699f74e61c50250ed4335bc8f400e127707d552a8999e
|
||||
F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303
|
||||
F test/substr.test a673e3763e247e9b5e497a6cacbaf3da2bd8ec8921c0677145c109f2e633f36b
|
||||
F test/subtype1.test 96fd2a59bfc845c955b5f339d23b37ef4d50de5f8a04acd1450a68605fa2e3e7
|
||||
@@ -2181,8 +2184,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 75c49267ec6b84c8aad0e264c34506e4b24f69475ae5def0ee7530ba3822c15d
|
||||
R 2e866f8f96424c36ead738f7cc32a381
|
||||
U dan
|
||||
Z b33421e6e016ff0d1ecfa51911613b2c
|
||||
P 3223fee0b93bbbe277b955a98c13bb583ded78109f8e601c9ec0a7bd3749fd55 aef5397569d65d2971367b0278fe3a6f42544cf771572e7d046e2472f052364d
|
||||
R 7195c1541663c387532db21aed885d33
|
||||
U drh
|
||||
Z 19135e17dd3bb54a10cd401bdceed81e
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
3223fee0b93bbbe277b955a98c13bb583ded78109f8e601c9ec0a7bd3749fd55
|
||||
8e8a27c77aa0ea5891968231e13a8caeade48b817419bbf6eda18ad217f1df63
|
||||
|
||||
114
src/alter.c
114
src/alter.c
@@ -2110,6 +2110,57 @@ static void renameTableTest(
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Return the number of bytes until the end of the next non-whitespace and
|
||||
** non-comment token. For the purpose of this function, a "(" token includes
|
||||
** all of the bytes through and including the matching ")", or until the
|
||||
** first illegal token, whichever comes first.
|
||||
**
|
||||
** Write the token type into *piToken.
|
||||
**
|
||||
** The value returned is the number of bytes in the token itself plus
|
||||
** the number of bytes of leading whitespace and comments skipped plus
|
||||
** all bytes through the next matching ")" if the token is TK_LP.
|
||||
**
|
||||
** Example: (Note: '.' used in place of '*' in the example z[] text)
|
||||
**
|
||||
** ,--------- *piToken := TK_RP
|
||||
** v
|
||||
** z[] = " /.comment./ --comment\n (two three four) five"
|
||||
** | |
|
||||
** |<-------------------------------------->|
|
||||
** |
|
||||
** `--- return value
|
||||
*/
|
||||
static int getConstraintToken(const u8 *z, int *piToken){
|
||||
int iOff = 0;
|
||||
int t = 0;
|
||||
do {
|
||||
iOff += sqlite3GetToken(&z[iOff], &t);
|
||||
}while( t==TK_SPACE || t==TK_COMMENT );
|
||||
|
||||
*piToken = t;
|
||||
|
||||
if( t==TK_LP ){
|
||||
int nNest = 1;
|
||||
while( nNest>0 ){
|
||||
iOff += sqlite3GetToken(&z[iOff], &t);
|
||||
if( t==TK_LP ){
|
||||
nNest++;
|
||||
}else if( t==TK_RP ){
|
||||
t = TK_LP;
|
||||
nNest--;
|
||||
}else if( t==TK_ILLEGAL ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*piToken = t;
|
||||
return iOff;
|
||||
}
|
||||
|
||||
/*
|
||||
** The implementation of internal UDF sqlite_drop_column().
|
||||
**
|
||||
@@ -2154,15 +2205,24 @@ static void dropColumnFunc(
|
||||
goto drop_column_done;
|
||||
}
|
||||
|
||||
pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName);
|
||||
if( iCol<pTab->nCol-1 ){
|
||||
RenameToken *pEnd;
|
||||
pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName);
|
||||
pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName);
|
||||
zEnd = (const char*)pEnd->t.z;
|
||||
}else{
|
||||
int eTok;
|
||||
assert( IsOrdinaryTable(pTab) );
|
||||
assert( iCol!=0 );
|
||||
/* Point pCol->t.z at the "," immediately preceding the definition of
|
||||
** the column being dropped. To do this, start at the name of the
|
||||
** previous column, and tokenize until the next ",". */
|
||||
pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol-1].zCnName);
|
||||
do {
|
||||
pCol->t.z += getConstraintToken((const u8*)pCol->t.z, &eTok);
|
||||
}while( eTok!=TK_COMMA );
|
||||
pCol->t.z--;
|
||||
zEnd = (const char*)&zSql[pTab->u.tab.addColOffset];
|
||||
while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--;
|
||||
}
|
||||
|
||||
zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd);
|
||||
@@ -2346,56 +2406,6 @@ static int getWhitespace(const u8 *z){
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Return the number of bytes until the end of the next non-whitespace and
|
||||
** non-comment token. For the purpose of this function, a "(" token includes
|
||||
** all of the bytes through and including the matching ")", or until the
|
||||
** first illegal token, whichever comes first.
|
||||
**
|
||||
** Write the token type into *piToken.
|
||||
**
|
||||
** The value returned is the number of bytes in the token itself plus
|
||||
** the number of bytes of leading whitespace and comments skipped plus
|
||||
** all bytes through the next matching ")" if the token is TK_LP.
|
||||
**
|
||||
** Example: (Note: '.' used in place of '*' in the example z[] text)
|
||||
**
|
||||
** ,--------- *piToken := TK_RP
|
||||
** v
|
||||
** z[] = " /.comment./ --comment\n (two three four) five"
|
||||
** | |
|
||||
** |<-------------------------------------->|
|
||||
** |
|
||||
** `--- return value
|
||||
*/
|
||||
static int getConstraintToken(const u8 *z, int *piToken){
|
||||
int iOff = 0;
|
||||
int t = 0;
|
||||
do {
|
||||
iOff += sqlite3GetToken(&z[iOff], &t);
|
||||
}while( t==TK_SPACE || t==TK_COMMENT );
|
||||
|
||||
*piToken = t;
|
||||
|
||||
if( t==TK_LP ){
|
||||
int nNest = 1;
|
||||
while( nNest>0 ){
|
||||
iOff += sqlite3GetToken(&z[iOff], &t);
|
||||
if( t==TK_LP ){
|
||||
nNest++;
|
||||
}else if( t==TK_RP ){
|
||||
t = TK_LP;
|
||||
nNest--;
|
||||
}else if( t==TK_ILLEGAL ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*piToken = t;
|
||||
return iOff;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument z points into the body of a constraint - specifically the
|
||||
** second token of the constraint definition. For a named constraint,
|
||||
|
||||
73
src/expr.c
73
src/expr.c
@@ -935,34 +935,22 @@ Expr *sqlite3ExprAlloc(
|
||||
int dequote /* True to dequote */
|
||||
){
|
||||
Expr *pNew;
|
||||
int nExtra = 0;
|
||||
int iValue = 0;
|
||||
int nExtra = pToken ? pToken->n+1 : 0;
|
||||
|
||||
assert( db!=0 );
|
||||
if( pToken ){
|
||||
if( op!=TK_INTEGER || pToken->z==0
|
||||
|| sqlite3GetInt32(pToken->z, &iValue)==0 ){
|
||||
nExtra = pToken->n+1; /* tag-20240227-a */
|
||||
assert( iValue>=0 );
|
||||
}
|
||||
}
|
||||
pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
|
||||
if( pNew ){
|
||||
memset(pNew, 0, sizeof(Expr));
|
||||
pNew->op = (u8)op;
|
||||
pNew->iAgg = -1;
|
||||
if( pToken ){
|
||||
if( nExtra==0 ){
|
||||
pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
|
||||
pNew->u.iValue = iValue;
|
||||
}else{
|
||||
pNew->u.zToken = (char*)&pNew[1];
|
||||
assert( pToken->z!=0 || pToken->n==0 );
|
||||
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
|
||||
pNew->u.zToken[pToken->n] = 0;
|
||||
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
|
||||
sqlite3DequoteExpr(pNew);
|
||||
}
|
||||
if( nExtra ){
|
||||
assert( pToken!=0 );
|
||||
pNew->u.zToken = (char*)&pNew[1];
|
||||
assert( pToken->z!=0 || pToken->n==0 );
|
||||
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
|
||||
pNew->u.zToken[pToken->n] = 0;
|
||||
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
|
||||
sqlite3DequoteExpr(pNew);
|
||||
}
|
||||
}
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
@@ -987,6 +975,24 @@ Expr *sqlite3Expr(
|
||||
return sqlite3ExprAlloc(db, op, &x, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate an expression for a 32-bit signed integer literal.
|
||||
*/
|
||||
Expr *sqlite3ExprInt32(sqlite3 *db, int iVal){
|
||||
Expr *pNew = sqlite3DbMallocRawNN(db, sizeof(Expr));
|
||||
if( pNew ){
|
||||
memset(pNew, 0, sizeof(Expr));
|
||||
pNew->op = TK_INTEGER;
|
||||
pNew->iAgg = -1;
|
||||
pNew->flags = EP_IntValue|EP_Leaf|(iVal?EP_IsTrue:EP_IsFalse);
|
||||
pNew->u.iValue = iVal;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
pNew->nHeight = 1;
|
||||
#endif
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attach subtrees pLeft and pRight to the Expr node pRoot.
|
||||
**
|
||||
@@ -1149,7 +1155,7 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
|
||||
){
|
||||
sqlite3ExprDeferredDelete(pParse, pLeft);
|
||||
sqlite3ExprDeferredDelete(pParse, pRight);
|
||||
return sqlite3Expr(db, TK_INTEGER, "0");
|
||||
return sqlite3ExprInt32(db, 0);
|
||||
}else{
|
||||
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
|
||||
}
|
||||
@@ -2624,7 +2630,7 @@ static int exprIsConst(Parse *pParse, Expr *p, int initFlag){
|
||||
|
||||
/*
|
||||
** Walk an expression tree. Return non-zero if the expression is constant
|
||||
** and 0 if it involves variables or function calls.
|
||||
** or return zero if the expression involves variables or function calls.
|
||||
**
|
||||
** For the purposes of this function, a double-quoted string (ex: "abc")
|
||||
** is considered a variable but a single-quoted string (ex: 'abc') is
|
||||
@@ -3891,9 +3897,22 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
pParse->nMem += nReg;
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
dest.eDest = SRT_Mem;
|
||||
dest.iSdst = dest.iSDParm;
|
||||
if( (pSel->selFlags&SF_Distinct) && pSel->pLimit && pSel->pLimit->pRight ){
|
||||
/* If there is both a DISTINCT and an OFFSET clause, then allocate
|
||||
** a separate dest.iSdst array for sqlite3Select() and other
|
||||
** routines to populate. In this case results will be copied over
|
||||
** into the dest.iSDParm array only after OFFSET processing. This
|
||||
** ensures that in the case where OFFSET excludes all rows, the
|
||||
** dest.iSDParm array is not left populated with the contents of the
|
||||
** last row visited - it should be all NULLs if all rows were
|
||||
** excluded by OFFSET. */
|
||||
dest.iSdst = pParse->nMem+1;
|
||||
pParse->nMem += nReg;
|
||||
}else{
|
||||
dest.iSdst = dest.iSDParm;
|
||||
}
|
||||
dest.nSdst = nReg;
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, pParse->nMem);
|
||||
VdbeComment((v, "Init subquery result"));
|
||||
}else{
|
||||
dest.eDest = SRT_Exists;
|
||||
@@ -3909,7 +3928,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
|| (pLeft->u.iValue!=1 && pLeft->u.iValue!=0)
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
pLimit = sqlite3Expr(db, TK_INTEGER, "0");
|
||||
pLimit = sqlite3ExprInt32(db, 0);
|
||||
if( pLimit ){
|
||||
pLimit->affExpr = SQLITE_AFF_NUMERIC;
|
||||
pLimit = sqlite3PExpr(pParse, TK_NE,
|
||||
@@ -3920,7 +3939,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
}
|
||||
}else{
|
||||
/* If there is no pre-existing limit add a limit of 1 */
|
||||
pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
|
||||
pLimit = sqlite3ExprInt32(pParse->db, 1);
|
||||
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
|
||||
}
|
||||
pSel->iLimit = 0;
|
||||
|
||||
79
src/parse.y
79
src/parse.y
@@ -1169,7 +1169,12 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
|
||||
term(A) ::= NULL|FLOAT|BLOB(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
|
||||
term(A) ::= STRING(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
|
||||
term(A) ::= INTEGER(X). {
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
|
||||
int iValue;
|
||||
if( sqlite3GetInt32(X.z, &iValue)==0 ){
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 0);
|
||||
}else{
|
||||
A = sqlite3ExprInt32(pParse->db, iValue);
|
||||
}
|
||||
if( A ) A->w.iOfst = (int)(X.z - pParse->zTail);
|
||||
}
|
||||
expr(A) ::= VARIABLE(X). {
|
||||
@@ -1351,43 +1356,67 @@ expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
|
||||
if( A ) A->flags |= EP_InfixFunc;
|
||||
}
|
||||
|
||||
expr(A) ::= expr(A) ISNULL|NOTNULL(E). {A = sqlite3PExpr(pParse,@E,A,0);}
|
||||
expr(A) ::= expr(A) NOT NULL. {A = sqlite3PExpr(pParse,TK_NOTNULL,A,0);}
|
||||
|
||||
%include {
|
||||
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
|
||||
** unary TK_ISNULL or TK_NOTNULL expression. */
|
||||
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){
|
||||
pA->op = (u8)op;
|
||||
sqlite3ExprDelete(db, pA->pRight);
|
||||
pA->pRight = 0;
|
||||
/* Create a TK_ISNULL or TK_NOTNULL expression, perhaps optimized to
|
||||
** to TK_TRUEFALSE, if possible */
|
||||
static Expr *sqlite3PExprIsNull(
|
||||
Parse *pParse, /* Parsing context */
|
||||
int op, /* TK_ISNULL or TK_NOTNULL */
|
||||
Expr *pLeft /* Operand */
|
||||
){
|
||||
Expr *p = pLeft;
|
||||
assert( op==TK_ISNULL || op==TK_NOTNULL );
|
||||
assert( pLeft!=0 );
|
||||
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
|
||||
p = p->pLeft;
|
||||
assert( p!=0 );
|
||||
}
|
||||
switch( p->op ){
|
||||
case TK_INTEGER:
|
||||
case TK_STRING:
|
||||
case TK_FLOAT:
|
||||
case TK_BLOB:
|
||||
sqlite3ExprDeferredDelete(pParse, pLeft);
|
||||
return sqlite3ExprInt32(pParse->db, op==TK_NOTNULL);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return sqlite3PExpr(pParse, op, pLeft, 0);
|
||||
}
|
||||
|
||||
/* Create a TK_IS or TK_ISNOT operator, perhaps optimized to
|
||||
** TK_ISNULL or TK_NOTNULL or TK_TRUEFALSE. */
|
||||
static Expr *sqlite3PExprIs(
|
||||
Parse *pParse, /* Parsing context */
|
||||
int op, /* TK_IS or TK_ISNOT */
|
||||
Expr *pLeft, /* Left operand */
|
||||
Expr *pRight /* Right operand */
|
||||
){
|
||||
if( pRight && pRight->op==TK_NULL ){
|
||||
sqlite3ExprDeferredDelete(pParse, pRight);
|
||||
return sqlite3PExprIsNull(pParse, op==TK_IS ? TK_ISNULL : TK_NOTNULL, pLeft);
|
||||
}
|
||||
return sqlite3PExpr(pParse, op, pLeft, pRight);
|
||||
}
|
||||
}
|
||||
|
||||
// expr1 IS expr2
|
||||
// expr1 IS NOT expr2
|
||||
expr(A) ::= expr(A) ISNULL|NOTNULL(E). {A = sqlite3PExprIsNull(pParse,@E,A);}
|
||||
expr(A) ::= expr(A) NOT NULL. {A = sqlite3PExprIsNull(pParse,TK_NOTNULL,A);}
|
||||
|
||||
// expr1 IS expr2 same as expr1 IS NOT DISTICT FROM expr2
|
||||
// expr1 IS NOT expr2 same as expr1 IS DISTINCT FROM expr2
|
||||
//
|
||||
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL. If expr2
|
||||
// is any other expression, code as TK_IS or TK_ISNOT.
|
||||
//
|
||||
expr(A) ::= expr(A) IS expr(Y). {
|
||||
A = sqlite3PExpr(pParse,TK_IS,A,Y);
|
||||
binaryToUnaryIfNull(pParse, Y, A, TK_ISNULL);
|
||||
A = sqlite3PExprIs(pParse, TK_IS, A, Y);
|
||||
}
|
||||
expr(A) ::= expr(A) IS NOT expr(Y). {
|
||||
A = sqlite3PExpr(pParse,TK_ISNOT,A,Y);
|
||||
binaryToUnaryIfNull(pParse, Y, A, TK_NOTNULL);
|
||||
A = sqlite3PExprIs(pParse, TK_ISNOT, A, Y);
|
||||
}
|
||||
expr(A) ::= expr(A) IS NOT DISTINCT FROM expr(Y). {
|
||||
A = sqlite3PExpr(pParse,TK_IS,A,Y);
|
||||
binaryToUnaryIfNull(pParse, Y, A, TK_ISNULL);
|
||||
A = sqlite3PExprIs(pParse, TK_IS, A, Y);
|
||||
}
|
||||
expr(A) ::= expr(A) IS DISTINCT FROM expr(Y). {
|
||||
A = sqlite3PExpr(pParse,TK_ISNOT,A,Y);
|
||||
binaryToUnaryIfNull(pParse, Y, A, TK_NOTNULL);
|
||||
A = sqlite3PExprIs(pParse, TK_ISNOT, A, Y);
|
||||
}
|
||||
|
||||
expr(A) ::= NOT(B) expr(X).
|
||||
|
||||
@@ -1656,10 +1656,8 @@ static int resolveCompoundOrderBy(
|
||||
/* Convert the ORDER BY term into an integer column number iCol,
|
||||
** taking care to preserve the COLLATE clause if it exists. */
|
||||
if( !IN_RENAME_OBJECT ){
|
||||
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
|
||||
Expr *pNew = sqlite3ExprInt32(db, iCol);
|
||||
if( pNew==0 ) return 1;
|
||||
pNew->flags |= EP_IntValue;
|
||||
pNew->u.iValue = iCol;
|
||||
if( pItem->pExpr==pE ){
|
||||
pItem->pExpr = pNew;
|
||||
}else{
|
||||
|
||||
13
src/select.c
13
src/select.c
@@ -1445,9 +1445,14 @@ static void selectInnerLoop(
|
||||
assert( nResultCol<=pDest->nSdst );
|
||||
pushOntoSorter(
|
||||
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
|
||||
pDest->iSDParm = regResult;
|
||||
}else{
|
||||
assert( nResultCol==pDest->nSdst );
|
||||
assert( regResult==iParm );
|
||||
if( regResult!=iParm ){
|
||||
/* This occurs in cases where the SELECT had both a DISTINCT and
|
||||
** an OFFSET clause. */
|
||||
sqlite3VdbeAddOp3(v, OP_Copy, regResult, iParm, nResultCol-1);
|
||||
}
|
||||
/* The LIMIT clause will jump out of the loop for us */
|
||||
}
|
||||
break;
|
||||
@@ -3612,10 +3617,8 @@ static int multiSelectOrderBy(
|
||||
if( pItem->u.x.iOrderByCol==i ) break;
|
||||
}
|
||||
if( j==nOrderBy ){
|
||||
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
|
||||
Expr *pNew = sqlite3ExprInt32(db, i);
|
||||
if( pNew==0 ) return SQLITE_NOMEM_BKPT;
|
||||
pNew->flags |= EP_IntValue;
|
||||
pNew->u.iValue = i;
|
||||
p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
|
||||
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
|
||||
}
|
||||
@@ -7131,7 +7134,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
|
||||
&& pExpr->pAggInfo==0
|
||||
){
|
||||
sqlite3 *db = pWalker->pParse->db;
|
||||
Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
|
||||
Expr *pNew = sqlite3ExprInt32(db, 1);
|
||||
if( pNew ){
|
||||
Expr *pWhere = pS->pWhere;
|
||||
SWAP(Expr, *pNew, *pExpr);
|
||||
|
||||
@@ -2391,6 +2391,8 @@ static void shellFormatSchema(
|
||||
for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
|
||||
if( c==cEnd ){
|
||||
cEnd = 0;
|
||||
}else if( cEnd!=0){
|
||||
/* No-op */
|
||||
}else if( c=='"' || c=='\'' || c=='`' ){
|
||||
cEnd = c;
|
||||
}else if( c=='[' ){
|
||||
|
||||
@@ -4933,6 +4933,7 @@ int sqlite3NoTempsInRange(Parse*,int,int);
|
||||
#endif
|
||||
Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
|
||||
Expr *sqlite3Expr(sqlite3*,int,const char*);
|
||||
Expr *sqlite3ExprInt32(sqlite3*,int);
|
||||
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
|
||||
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
|
||||
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
|
||||
|
||||
@@ -2361,6 +2361,10 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
|
||||
}else if( strcmp(zArg,"-null")==0 ){
|
||||
qrf.zNull = Tcl_GetString(objv[i+1]);
|
||||
i++;
|
||||
}else if( strcmp(zArg,"-version")==0 ){
|
||||
/* Undocumented. Testing use only */
|
||||
qrf.iVersion = atoi(Tcl_GetString(objv[i+1]));
|
||||
i++;
|
||||
}else{
|
||||
Tcl_AppendResult(pDb->interp, "unknown option: ", zArg, (char*)0);
|
||||
rc = TCL_ERROR;
|
||||
|
||||
@@ -1609,13 +1609,11 @@ static void whereAddLimitExpr(
|
||||
int iVal = 0;
|
||||
|
||||
if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){
|
||||
Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
|
||||
Expr *pVal = sqlite3ExprInt32(db, iVal);
|
||||
if( pVal==0 ) return;
|
||||
ExprSetProperty(pVal, EP_IntValue);
|
||||
pVal->u.iValue = iVal;
|
||||
pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
|
||||
}else{
|
||||
Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0);
|
||||
Expr *pVal = sqlite3ExprAlloc(db, TK_REGISTER, 0, 0);
|
||||
if( pVal==0 ) return;
|
||||
pVal->iTable = iReg;
|
||||
pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
|
||||
|
||||
@@ -717,7 +717,7 @@ void sqlite3WindowUpdate(
|
||||
pWin->eEnd = aUp[i].eEnd;
|
||||
pWin->eExclude = 0;
|
||||
if( pWin->eStart==TK_FOLLOWING ){
|
||||
pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
|
||||
pWin->pStart = sqlite3ExprInt32(db, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1062,9 +1062,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
** keep everything legal in this case.
|
||||
*/
|
||||
if( pSublist==0 ){
|
||||
pSublist = sqlite3ExprListAppend(pParse, 0,
|
||||
sqlite3Expr(db, TK_INTEGER, "0")
|
||||
);
|
||||
pSublist = sqlite3ExprListAppend(pParse, 0, sqlite3ExprInt32(db, 0));
|
||||
}
|
||||
|
||||
pSub = sqlite3SelectNew(
|
||||
|
||||
@@ -778,4 +778,52 @@ do_execsql_test 31.2 {
|
||||
SELECT rr FROM t1 LIMIT 1
|
||||
} {5.0}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 32.1.0 {
|
||||
CREATE TABLE t1(
|
||||
a INT,
|
||||
b INT,
|
||||
-- comment with comma
|
||||
c INT
|
||||
);
|
||||
}
|
||||
do_execsql_test 32.1.1 {
|
||||
ALTER TABLE t1 DROP COLUMN c;
|
||||
}
|
||||
do_execsql_test 32.1.2 {
|
||||
SELECT sql FROM sqlite_schema
|
||||
} {{CREATE TABLE t1(
|
||||
a INT,
|
||||
b INT)}}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 32.2.0 {
|
||||
CREATE TABLE t1(
|
||||
a INT,
|
||||
b INT,
|
||||
-- comment with, comma
|
||||
c INT
|
||||
);
|
||||
}
|
||||
do_execsql_test 32.2.1 {
|
||||
ALTER TABLE t1 DROP COLUMN c;
|
||||
}
|
||||
do_execsql_test 32.2.2 {
|
||||
SELECT sql FROM sqlite_schema
|
||||
} {{CREATE TABLE t1(
|
||||
a INT,
|
||||
b INT)}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 33.1 {
|
||||
CREATE TABLE x1(a TEXT, b INTEGER, c CHECK(c!=0));
|
||||
}
|
||||
|
||||
do_execsql_test 33.2 {
|
||||
ALTER TABLE x1 DROP COLUMN b;
|
||||
SELECT sql FROM sqlite_schema;
|
||||
} {{CREATE TABLE x1(a TEXT, c CHECK(c!=0))}}
|
||||
|
||||
finish_test
|
||||
|
||||
37
test/qrf05.test
Normal file
37
test/qrf05.test
Normal file
@@ -0,0 +1,37 @@
|
||||
# 2025-12-02
|
||||
#
|
||||
# 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 cases for the Query Result Formatter (QRF)
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix qrf05
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a INT NOT NULL);
|
||||
}
|
||||
do_test 1.1 {
|
||||
set rc [catch {db format -style list \
|
||||
{INSERT INTO t1 VALUES(123) RETURNING *}} msg]
|
||||
list $rc [string trim $msg]
|
||||
} {0 123}
|
||||
do_test 1.2 {
|
||||
set rc [catch {db format -style list \
|
||||
{INSERT INTO t1 VALUES(NULL) RETURNING *}} msg]
|
||||
list $rc [string trim $msg]
|
||||
} {1 {NOT NULL constraint failed: t1.a}}
|
||||
do_test 1.3 {
|
||||
set rc [catch {db format -version 99 {SELECT * FROM t1}} msg]
|
||||
list $rc [string trim $msg]
|
||||
} {1 {unusable sqlite3_qrf_spec.iVersion (99)}}
|
||||
|
||||
finish_test
|
||||
576
test/qrf06.test
Normal file
576
test/qrf06.test
Normal file
@@ -0,0 +1,576 @@
|
||||
# 2025-12-02
|
||||
#
|
||||
# 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 cases for the Query Result Formatter (QRF), and especially
|
||||
# the sqlite3_qrf_wcwidth() function and its utilization.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix qrf06
|
||||
|
||||
# Data
|
||||
db eval {
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE language(name TEXT);
|
||||
INSERT INTO language(name) VALUES
|
||||
('العربية'),
|
||||
('Deutsch'),
|
||||
('English'),
|
||||
('Español'),
|
||||
('فارسی'),
|
||||
('Français'),
|
||||
('Italiano'),
|
||||
('مصرى'),
|
||||
('Nederlands'),
|
||||
('日本語'),
|
||||
('Polski'),
|
||||
('Português'),
|
||||
('Sinugboanong Binisaya'),
|
||||
('Svenska'),
|
||||
('Українська'),
|
||||
('Tiếng Việt'),
|
||||
('Winaray'),
|
||||
('中文'),
|
||||
('Русский'),
|
||||
('Afrikaans'),
|
||||
('Shqip'),
|
||||
('Asturianu'),
|
||||
('Azərbaycanca'),
|
||||
('Български'),
|
||||
('閩南語 / Bân-lâm-gú'),
|
||||
('বাংলা'),
|
||||
('Беларуская'),
|
||||
('Català'),
|
||||
('Čeština'),
|
||||
('Cymraeg'),
|
||||
('Dansk'),
|
||||
('Eesti'),
|
||||
('Ελληνικά'),
|
||||
('Esperanto'),
|
||||
('Euskara'),
|
||||
('Galego'),
|
||||
('한국어'),
|
||||
('Հայերեն'),
|
||||
('हिन्दी'),
|
||||
('Hrvatski'),
|
||||
('Bahasa Indonesia'),
|
||||
('עברית'),
|
||||
('ქართული'),
|
||||
('Ladin'),
|
||||
('Latina'),
|
||||
('Latviešu'),
|
||||
('Lietuvių'),
|
||||
('Magyar'),
|
||||
('Македонски'),
|
||||
('Malagasy'),
|
||||
('मराठी'),
|
||||
('Bahasa Melayu'),
|
||||
('Bahaso Minangkabau'),
|
||||
('မြန်မာဘာသာ'),
|
||||
('Norskbokmålnynorsk'),
|
||||
('Нохчийн'),
|
||||
('Oʻzbekcha / Ўзбекча'),
|
||||
('Қазақша / Qazaqşa / قازاقشا'),
|
||||
('Română'),
|
||||
('Simple English'),
|
||||
('Slovenčina'),
|
||||
('Slovenščina'),
|
||||
('Српски / Srpski'),
|
||||
('Srpskohrvatski / Српскохрватски'),
|
||||
('Suomi'),
|
||||
('Kiswahili'),
|
||||
('தமிழ்'),
|
||||
('Татарча / Tatarça'),
|
||||
('తెలుగు'),
|
||||
('ภาษาไทย'),
|
||||
('Тоҷикӣ'),
|
||||
('تۆرکجه'),
|
||||
('Türkçe'),
|
||||
('اردو'),
|
||||
('粵語'),
|
||||
('Bahsa Acèh'),
|
||||
('Alemannisch'),
|
||||
('አማርኛ'),
|
||||
('Aragonés'),
|
||||
('Արեւմտահայերէն'),
|
||||
('Bahasa Hulontalo'),
|
||||
('Basa Bali'),
|
||||
('Bahasa Banjar'),
|
||||
('Basa Banyumasan'),
|
||||
('Башҡортса'),
|
||||
('Беларуская (тарашкевіца)'),
|
||||
('Bikol Central'),
|
||||
('বিষ্ণুপ্রিয়া মণিপুরী'),
|
||||
('Boarisch'),
|
||||
('Bosanski'),
|
||||
('Brezhoneg'),
|
||||
('Чӑвашла'),
|
||||
('Dagbanli'),
|
||||
('الدارجة'),
|
||||
('Diné Bizaad'),
|
||||
('Emigliàn–Rumagnòl'),
|
||||
('Fiji Hindi'),
|
||||
('Føroyskt'),
|
||||
('Frysk'),
|
||||
('Fulfulde'),
|
||||
('Gaeilge'),
|
||||
('Gàidhlig'),
|
||||
('گیلکی'),
|
||||
('ગુજરાતી'),
|
||||
('Hak-kâ-ngî / 客家語'),
|
||||
('Hausa'),
|
||||
('Hornjoserbsce'),
|
||||
('Ido'),
|
||||
('Igbo'),
|
||||
('Ilokano'),
|
||||
('Interlingua'),
|
||||
('Interlingue'),
|
||||
('Ирон'),
|
||||
('Íslenska'),
|
||||
('Jawa'),
|
||||
('ಕನ್ನಡ'),
|
||||
('Kapampangan'),
|
||||
('ភាសាខ្មែរ'),
|
||||
('Kotava'),
|
||||
('Kreyòl Ayisyen'),
|
||||
('Kurdî / كوردی'),
|
||||
('کوردیی ناوەندی'),
|
||||
('Кыргызча'),
|
||||
('Кырык мары'),
|
||||
('Lëtzebuergesch'),
|
||||
('Lìgure'),
|
||||
('Limburgs'),
|
||||
('Lombard'),
|
||||
('मैथिली'),
|
||||
('മലയാളം'),
|
||||
('მარგალური'),
|
||||
('مازِرونی'),
|
||||
('Mìng-dĕ̤ng-ngṳ̄ / 閩東語'),
|
||||
('Монгол'),
|
||||
('Napulitano'),
|
||||
('नेपाल भाषा'),
|
||||
('Nordfriisk'),
|
||||
('Occitan'),
|
||||
('Олык марий'),
|
||||
('ଓଡି଼ଆ'),
|
||||
('অসমীযা়'),
|
||||
('ਪੰਜਾਬੀ'),
|
||||
('پنجابی (شاہ مکھی)'),
|
||||
('پښتو'),
|
||||
('Piemontèis'),
|
||||
('Plattdüütsch'),
|
||||
('Qaraqalpaqsha'),
|
||||
('Qırımtatarca'),
|
||||
('Runa Simi'),
|
||||
('Русиньскый'),
|
||||
('संस्कृतम्'),
|
||||
('ᱥᱟᱱᱛᱟᱲᱤ'),
|
||||
('سرائیکی'),
|
||||
('Саха Тыла'),
|
||||
('Scots'),
|
||||
('ChiShona'),
|
||||
('Sicilianu'),
|
||||
('සිංහල'),
|
||||
('سنڌي'),
|
||||
('Ślůnski'),
|
||||
('Basa Sunda'),
|
||||
('Taclḥit'),
|
||||
('Tagalog'),
|
||||
('ၽႃႇသႃႇတႆး'),
|
||||
('ⵜⴰⵎⴰⵣⵉⵖⵜ ⵜⴰⵏⴰⵡⴰⵢⵜ'),
|
||||
('tolışi'),
|
||||
('chiTumbuka'),
|
||||
('Basa Ugi'),
|
||||
('Vèneto'),
|
||||
('Volapük'),
|
||||
('Walon'),
|
||||
('文言'),
|
||||
('吴语'),
|
||||
('ייִדיש'),
|
||||
('Yorùbá'),
|
||||
('Zazaki'),
|
||||
('žemaitėška'),
|
||||
('isiZulu'),
|
||||
('नेपाली'),
|
||||
('ꯃꯤꯇꯩ ꯂꯣꯟ'),
|
||||
('Dzhudezmo / לאדינו'),
|
||||
('Адыгэбзэ'),
|
||||
('Ænglisc'),
|
||||
('Anarâškielâ'),
|
||||
('अंगिका'),
|
||||
('Аԥсшәа'),
|
||||
('armãneashti'),
|
||||
('Arpitan'),
|
||||
('atikamekw'),
|
||||
('ܐܬܘܪܝܐ'),
|
||||
('Avañe’ẽ'),
|
||||
('Авар'),
|
||||
('Aymar'),
|
||||
('Batak Toba'),
|
||||
('Betawi'),
|
||||
('भोजपुरी'),
|
||||
('Bislama'),
|
||||
('བོད་ཡིག'),
|
||||
('Буряад'),
|
||||
('Chavacano de Zamboanga'),
|
||||
('Chichewa'),
|
||||
('Corsu'),
|
||||
('Vahcuengh / 話僮'),
|
||||
('Dagaare'),
|
||||
('Davvisámegiella'),
|
||||
('Deitsch'),
|
||||
('ދިވެހިބަސް'),
|
||||
('Dolnoserbski'),
|
||||
('Dusun Bundu-liwan'),
|
||||
('Эрзянь'),
|
||||
('Estremeñu'),
|
||||
('Eʋegbe'),
|
||||
('Farefare'),
|
||||
('Fɔ̀ngbè'),
|
||||
('Furlan'),
|
||||
('Gaelg'),
|
||||
('Gagauz'),
|
||||
('ГӀалгӀай'),
|
||||
('Ghanaian Pidgin'),
|
||||
('Gĩkũyũ'),
|
||||
('赣语 / 贛語'),
|
||||
('Gungbe'),
|
||||
('Хальмг'),
|
||||
('ʻŌlelo Hawaiʻi'),
|
||||
('Ikinyarwanda'),
|
||||
('Jaku Iban'),
|
||||
('Kabɩyɛ'),
|
||||
('Yerwa Kanuri'),
|
||||
('Kaszëbsczi'),
|
||||
('Kernewek'),
|
||||
('Коми'),
|
||||
('Перем коми'),
|
||||
('Kongo'),
|
||||
('कोंकणी / Konknni'),
|
||||
('كٲشُر'),
|
||||
('Kriyòl Gwiyannen'),
|
||||
('Kumoring'),
|
||||
('Kʋsaal'),
|
||||
('ພາສາລາວ'),
|
||||
('Лакку'),
|
||||
('Latgaļu'),
|
||||
('Лезги'),
|
||||
('Li Niha'),
|
||||
('Lingála'),
|
||||
('Lingua Franca Nova'),
|
||||
('livvinkarjala'),
|
||||
('lojban'),
|
||||
('Luganda'),
|
||||
('Madhurâ'),
|
||||
('Malti'),
|
||||
('Mandailing'),
|
||||
('Māori'),
|
||||
('Mfantse'),
|
||||
('Mirandés'),
|
||||
('Мокшень'),
|
||||
('ဘာသာ မန်'),
|
||||
('Moore'),
|
||||
('ߒߞߏ'),
|
||||
('Na Vosa Vaka-Viti'),
|
||||
('Nāhuatlahtōlli'),
|
||||
('Naijá'),
|
||||
('Nedersaksisch'),
|
||||
('Nouormand / Normaund'),
|
||||
('Novial'),
|
||||
('Afaan Oromoo'),
|
||||
('ပအိုဝ်ႏဘာႏသာႏ'),
|
||||
('Pangasinán'),
|
||||
('Pangcah'),
|
||||
('Papiamentu'),
|
||||
('Patois'),
|
||||
('Pfälzisch'),
|
||||
('Picard'),
|
||||
('Къарачай–малкъар'),
|
||||
('Ripoarisch'),
|
||||
('Rumantsch'),
|
||||
('Sakizaya'),
|
||||
('Gagana Sāmoa'),
|
||||
('Sardu'),
|
||||
('Seediq'),
|
||||
('Seeltersk'),
|
||||
('Sesotho'),
|
||||
('Sesotho sa Leboa'),
|
||||
('Setswana'),
|
||||
('ꠍꠤꠟꠐꠤ'),
|
||||
('Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ'),
|
||||
('Soomaaliga'),
|
||||
('Sranantongo'),
|
||||
('SiSwati'),
|
||||
('Reo tahiti'),
|
||||
('Taqbaylit'),
|
||||
('Tarandíne'),
|
||||
('Tayal'),
|
||||
('Tetun'),
|
||||
('Tok Pisin'),
|
||||
('faka Tonga'),
|
||||
('Türkmençe'),
|
||||
('Twi'),
|
||||
('Tyap'),
|
||||
('Тыва дыл'),
|
||||
('Удмурт'),
|
||||
('ئۇيغۇرچه'),
|
||||
('Vepsän'),
|
||||
('võro'),
|
||||
('West-Vlams'),
|
||||
('Wolof'),
|
||||
('isiXhosa'),
|
||||
('Zeêuws'),
|
||||
('алтай тил'),
|
||||
('अवधी'),
|
||||
('डोटेली'),
|
||||
('ತುಳು'),
|
||||
('ရခိုင်'),
|
||||
('Bajau Sama'),
|
||||
('Bamanankan'),
|
||||
('Chamoru'),
|
||||
('རྫོང་ཁ'),
|
||||
('𐌲𐌿𐍄𐌹𐍃𐌺x'),
|
||||
('Igala'),
|
||||
('ᐃᓄᒃᑎᑐᑦ / Inuktitut'),
|
||||
('Iñupiak'),
|
||||
('isiNdebele seSewula'),
|
||||
('Kalaallisut'),
|
||||
('Nupe'),
|
||||
('Obolo'),
|
||||
('पालि'),
|
||||
('pinayuanan'),
|
||||
('Ποντιακά'),
|
||||
('romani čhib'),
|
||||
('Ikirundi'),
|
||||
('руски'),
|
||||
('Sängö'),
|
||||
('ᥖᥭᥰᥖᥬᥳᥑᥨᥒᥰ'),
|
||||
('ትግርኛ'),
|
||||
('Thuɔŋjäŋ'),
|
||||
('ᏣᎳᎩ'),
|
||||
('Tsėhesenėstsestotse'),
|
||||
('Xitsonga'),
|
||||
('Tshivenḓa'),
|
||||
('Wayuunaiki'),
|
||||
('адыгабзэ');
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_test 1.2 {
|
||||
set res \n[db format -style box {
|
||||
SELECT name, rowid AS id FROM language
|
||||
WHERE length(name)=2
|
||||
ORDER BY name
|
||||
}]
|
||||
set exp {
|
||||
┌──────┬─────┐
|
||||
│ name │ id │
|
||||
├──────┼─────┤
|
||||
│ 中文 │ 18 │
|
||||
│ 吴语 │ 173 │
|
||||
│ 文言 │ 172 │
|
||||
│ 粵語 │ 75 │
|
||||
└──────┴─────┘
|
||||
}
|
||||
if {$res ne $exp} {
|
||||
puts [list $res]
|
||||
puts [list $exp]
|
||||
}
|
||||
string compare $res $exp
|
||||
} {0}
|
||||
|
||||
do_test 1.3 {
|
||||
set res \n[db format -style box {
|
||||
SELECT name, rowid AS id FROM language
|
||||
WHERE length(name)=3
|
||||
ORDER BY name
|
||||
}]
|
||||
set exp {
|
||||
┌────────┬─────┐
|
||||
│ name │ id │
|
||||
├────────┼─────┤
|
||||
│ Ido │ 108 │
|
||||
│ Twi │ 297 │
|
||||
│ ߒߞߏ │ 258 │
|
||||
│ ᏣᎳᎩ │ 335 │
|
||||
│ 日本語 │ 10 │
|
||||
│ 한국어 │ 37 │
|
||||
└────────┴─────┘
|
||||
}
|
||||
if {$res ne $exp} {
|
||||
puts [list $res]
|
||||
puts [list $exp]
|
||||
}
|
||||
string compare $res $exp
|
||||
} {0}
|
||||
|
||||
do_test 1.4 {
|
||||
set res \n[db format -style box {
|
||||
SELECT name, rowid AS id FROM language
|
||||
WHERE length(name)=4
|
||||
ORDER BY name
|
||||
}]
|
||||
set exp {
|
||||
┌──────┬─────┐
|
||||
│ name │ id │
|
||||
├──────┼─────┤
|
||||
│ Igbo │ 109 │
|
||||
│ Jawa │ 115 │
|
||||
│ Nupe │ 323 │
|
||||
│ Tyap │ 298 │
|
||||
│ võro │ 303 │
|
||||
│ Авар │ 192 │
|
||||
│ Ирон │ 113 │
|
||||
│ Коми │ 231 │
|
||||
│ اردو │ 74 │
|
||||
│ سنڌي │ 159 │
|
||||
│ مصرى │ 8 │
|
||||
│ پښتو │ 144 │
|
||||
│ अवधी │ 309 │
|
||||
│ पालि │ 325 │
|
||||
│ ತುಳು │ 311 │
|
||||
│ ትግርኛ │ 333 │
|
||||
│ አማርኛ │ 78 │
|
||||
└──────┴─────┘
|
||||
}
|
||||
if {$res ne $exp} {
|
||||
puts [list $res]
|
||||
puts [list $exp]
|
||||
}
|
||||
string compare $res $exp
|
||||
} {0}
|
||||
|
||||
do_test 1.5 {
|
||||
set res \n[db format -style box {
|
||||
SELECT name, rowid AS id FROM language
|
||||
WHERE length(name)=5
|
||||
ORDER BY name
|
||||
}]
|
||||
set exp {
|
||||
┌───────┬─────┐
|
||||
│ name │ id │
|
||||
├───────┼─────┤
|
||||
│ Aymar │ 193 │
|
||||
│ Corsu │ 202 │
|
||||
│ Dansk │ 31 │
|
||||
│ Eesti │ 32 │
|
||||
│ Frysk │ 99 │
|
||||
│ Gaelg │ 216 │
|
||||
│ Hausa │ 106 │
|
||||
│ Igala │ 318 │
|
||||
│ Kongo │ 233 │
|
||||
│ Ladin │ 44 │
|
||||
│ Malti │ 250 │
|
||||
│ Moore │ 257 │
|
||||
│ Māori │ 252 │
|
||||
│ Naijá │ 261 │
|
||||
│ Obolo │ 324 │
|
||||
│ Sardu │ 278 │
|
||||
│ Scots │ 155 │
|
||||
│ Shqip │ 21 │
|
||||
│ Suomi │ 65 │
|
||||
│ Sängö │ 331 │
|
||||
│ Tayal │ 292 │
|
||||
│ Tetun │ 293 │
|
||||
│ Walon │ 171 │
|
||||
│ Wolof │ 305 │
|
||||
│ Лакку │ 240 │
|
||||
│ Лезги │ 242 │
|
||||
│ руски │ 330 │
|
||||
│ עברית │ 42 │
|
||||
│ فارسی │ 5 │
|
||||
│ كٲشُر │ 235 │
|
||||
│ گیلکی │ 103 │
|
||||
│ मराठी │ 51 │
|
||||
│ বাংলা │ 26 │
|
||||
│ ଓଡି଼ଆ │ 140 │
|
||||
│ தமிழ் │ 67 │
|
||||
│ ಕನ್ನಡ │ 116 │
|
||||
│ සිංහල │ 158 │
|
||||
│ ꠍꠤꠟꠐꠤ │ 284 │
|
||||
└───────┴─────┘
|
||||
}
|
||||
if {$res ne $exp} {
|
||||
puts [list $res]
|
||||
puts [list $exp]
|
||||
}
|
||||
string compare $res $exp
|
||||
} {0}
|
||||
|
||||
do_test 1.6 {
|
||||
set res \n[db format -style box {
|
||||
SELECT name, rowid AS id FROM language
|
||||
WHERE length(name)=6
|
||||
ORDER BY name
|
||||
}]
|
||||
set exp {
|
||||
┌────────┬─────┐
|
||||
│ name │ id │
|
||||
├────────┼─────┤
|
||||
│ Betawi │ 195 │
|
||||
│ Català │ 28 │
|
||||
│ Eʋegbe │ 212 │
|
||||
│ Furlan │ 215 │
|
||||
│ Gagauz │ 217 │
|
||||
│ Galego │ 36 │
|
||||
│ Gungbe │ 222 │
|
||||
│ Gĩkũyũ │ 220 │
|
||||
│ Kabɩyɛ │ 227 │
|
||||
│ Kotava │ 119 │
|
||||
│ Kʋsaal │ 238 │
|
||||
│ Latina │ 45 │
|
||||
│ Lìgure │ 126 │
|
||||
│ Magyar │ 48 │
|
||||
│ Novial │ 264 │
|
||||
│ Patois │ 270 │
|
||||
│ Picard │ 272 │
|
||||
│ Polski │ 11 │
|
||||
│ Română │ 59 │
|
||||
│ Seediq │ 279 │
|
||||
│ Türkçe │ 73 │
|
||||
│ Vepsän │ 302 │
|
||||
│ Vèneto │ 169 │
|
||||
│ Yorùbá │ 175 │
|
||||
│ Zazaki │ 176 │
|
||||
│ Zeêuws │ 307 │
|
||||
│ lojban │ 247 │
|
||||
│ tolışi │ 166 │
|
||||
│ Аԥсшәа │ 186 │
|
||||
│ Буряад │ 199 │
|
||||
│ Монгол │ 134 │
|
||||
│ Тоҷикӣ │ 71 │
|
||||
│ Удмурт │ 300 │
|
||||
│ Хальмг │ 223 │
|
||||
│ Эрзянь │ 210 │
|
||||
│ ייִדיש │ 174 │
|
||||
│ تۆرکجه │ 72 │
|
||||
│ ܐܬܘܪܝܐ │ 190 │
|
||||
│ अंगिका │ 185 │
|
||||
│ डोटेली │ 310 │
|
||||
│ नेपाली │ 179 │
|
||||
│ मैथिली │ 129 │
|
||||
│ हिन्दी │ 39 │
|
||||
│ ਪੰਜਾਬੀ │ 142 │
|
||||
│ తెలుగు │ 69 │
|
||||
│ മലയാളം │ 130 │
|
||||
│ རྫོང་ཁ │ 316 │
|
||||
│ ရခိုင် │ 312 │
|
||||
└────────┴─────┘
|
||||
}
|
||||
if {$res ne $exp} {
|
||||
puts [list $res]
|
||||
puts [list $exp]
|
||||
}
|
||||
string compare $res $exp
|
||||
} {0}
|
||||
|
||||
finish_test
|
||||
@@ -615,6 +615,20 @@ CREATE VIEW v1 AS SELECT y+1 FROM v2
|
||||
|
||||
catch {db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;}}
|
||||
}
|
||||
do_test shell1-3.21.5 {
|
||||
exec {*}$CLI -noinit test.db \
|
||||
{CREATE TABLE t2(a INTEGER PRIMARY KEY, b BLOB DEFAULT(jsonb('[]')),c TEXT NOT NULL)STRICT;} \
|
||||
{.schema -indent t2}
|
||||
} {CREATE TABLE t2(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b BLOB DEFAULT(jsonb('[]')),
|
||||
c TEXT NOT NULL
|
||||
)STRICT;}
|
||||
do_test shell1-3.21.6 {
|
||||
exec {*}$CLI -noinit test.db \
|
||||
{DROP TABLE t2;} \
|
||||
{.schema -indent t2}
|
||||
} {}
|
||||
|
||||
# .separator STRING Change column separator used by output and .import
|
||||
do_test shell1-3.22.1 {
|
||||
|
||||
@@ -215,4 +215,72 @@ do_execsql_test 5.1 {
|
||||
SELECT ( SELECT y FROM t2 WHERE x = y ORDER BY y, z) FROM t1;
|
||||
} {ALFKI ANATR}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(1234);
|
||||
}
|
||||
|
||||
do_execsql_test 6.1 {
|
||||
SELECT DISTINCT 'string' FROM t1 LIMIT 1 OFFSET 5;
|
||||
}
|
||||
|
||||
do_execsql_test 6.2 {
|
||||
SELECT (
|
||||
SELECT 'string' FROM t1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.3 {
|
||||
SELECT (
|
||||
SELECT DISTINCT 'string' FROM t1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.4 {
|
||||
SELECT (
|
||||
SELECT DISTINCT 'string' FROM t1 ORDER BY 1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.5 {
|
||||
SELECT (
|
||||
SELECT 'string' FROM t1 ORDER BY 1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.6 {
|
||||
SELECT (SELECT DISTINCT x, x FROM t1 LIMIT 1 OFFSET 5)==(1234, 1234)
|
||||
} {{}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 7.0 {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE INDEX i1 ON t1(x);
|
||||
INSERT INTO t1 VALUES(1234);
|
||||
}
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
SELECT (
|
||||
SELECT DISTINCT 'string' FROM t1 ORDER BY x LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 7.2 {
|
||||
DROP INDEX i1;
|
||||
CREATE UNIQUE INDEX i1 ON t1(x);
|
||||
}
|
||||
|
||||
do_execsql_test 7.3 {
|
||||
SELECT (
|
||||
SELECT DISTINCT x FROM t1 ORDER BY 1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 7.4 {
|
||||
SELECT (SELECT DISTINCT x FROM t1 ORDER BY +x LIMIT 1 OFFSET 0);
|
||||
} {1234}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user