Fossil SCM
Merge from trunk.
Commit
0ffacb525a925ba8da3152c9041fdf98e67b14f10faf30dc685dea5a8ab4e9c6
Parent
53010e9688857e0…
147 files changed
+1
-1
+826
-980
+2521
-708
+178
-42
+2
-2
+80
-25
+24
-31
+12
-8
+82
-36
+18
+16
-6
+225
+1
-1
+7
-27
+1
-1
+2
-1
+7
-1
+19
-22
+26
-4
+46
-8
+18
-3
+19
-13
+1
-1
+1
+29
-15
+3
-3
+2
-1
+18
-8
+2
-2
+9
-11
+6
-5
+4
-8
+2
-7
+3
-4
-1
+31
+2
-2
+4
-4
+16
-12
+27
-10
+73
-41
+1
-1
+131
-142
+7
-2
+13
+1
-1
+1
-1
+2
-2
+2
-2
+1
-1
+243
-92
+7
+6
-6
+4
-2
+156
-85
+3
+2
-2
+15
-5
+21
-62
+1
-1
+531
-34
+1
-1
+3
-3
+284
-164
+4
+12
-8
+9
+3
+4
-3
+42
-1
+24
-18
-139
+1
-1
+1
-1
-138
+138
+2
-2
+1
+10
-4
+13
+12
+3
-3
+11
-11
+11
-11
+147
-31
+5
-5
+2
-2
+7
-7
+6
-6
+5
-5
+2
-2
+6
-6
+1
-1
+3
-3
+2
-2
+409
-345
+8
-8
+1
-1
+1
-1
+1
-1
+2
-2
+4
-4
+1
-2
+1
-1
+4
-4
+6
-6
+5
-5
+2
-2
+1
-1
+1
-1
+1
-1
+1
-1
+9
-9
+22
-22
+24
-24
+18
-18
+5
+2
-2
+1
-1
+7
-7
+4
-4
+1
-1
+2
-2
+4
-4
+1
-1
+1
-1
+4
-4
+1
-1
+1
-1
+3
-3
+1
-1
+1
-1
+1
-1
+5
-5
+1
-1
+1
-1
+1
-1
+7
-7
+2
-2
+2
-2
+8
-8
+7
-7
+1
-1
+1
-1
+6
-6
~
VERSION
~
extsrc/shell.c
~
extsrc/sqlite3.c
~
extsrc/sqlite3.h
~
src/add.c
~
src/branch.c
~
src/browse.c
~
src/captcha.c
~
src/cgi.c
~
src/chat.c
~
src/checkin.c
~
src/checkout.c
~
src/clearsign.c
~
src/clone.c
~
src/comformat.c
~
src/content.c
~
src/cookies.c
~
src/copybtn.js
~
src/db.c
~
src/default.css
~
src/deltafunc.c
~
src/diff.c
~
src/diff.tcl
~
src/diffcmd.c
~
src/dispatch.c
~
src/doc.c
~
src/extcgi.c
~
src/finfo.c
~
src/forum.c
~
src/fossil.copybutton.js
~
src/fossil.dom.js
~
src/fossil.numbered-lines.js
~
src/fossil.page.chat.js
~
src/fossil.page.pikchrshow.js
~
src/fossil.page.pikchrshowasm.js
~
src/fossil.page.ticket.js
~
src/fossil.page.wikiedit.js
~
src/graph.js
~
src/href.js
~
src/http.c
~
src/info.c
~
src/json.c
~
src/login.c
~
src/main.c
~
src/main.mk
~
src/manifest.c
~
src/markdown.md
~
src/match.c
~
src/pikchrshow.c
~
src/printf.c
~
src/regexp.c
~
src/robot.c
~
src/search.c
~
src/security_audit.c
~
src/setup.c
~
src/sitemap.c
~
src/skins.c
~
src/stash.c
~
src/style.c
~
src/tag.c
~
src/tar.c
~
src/th_lang.c
~
src/th_main.c
~
src/timeline.c
~
src/tkt.c
~
src/tktsetup.c
~
src/unversioned.c
~
src/url.c
~
src/user.c
~
src/util.c
~
src/xfer.c
~
src/zip.c
~
test/commit-warning.test
~
test/json.test
~
test/set-manifest.test
-
test/settings.test
~
test/settings.test.off
+
test/settings.test.off
~
tools/makeheaders.c
~
tools/makemake.tcl
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.msc
~
www/aboutcgi.wiki
~
www/aboutdownload.wiki
~
www/alerts.md
~
www/antibot.wiki
~
www/backoffice.md
~
www/backup.md
~
www/blame.wiki
~
www/blockchain.md
~
www/branching.wiki
~
www/build.wiki
~
www/caps/admin-v-setup.md
~
www/caps/login-groups.md
~
www/caps/ref.html
~
www/cgi.wiki
~
www/changes.wiki
~
www/chat.md
~
www/childprojects.wiki
~
www/chroot.md
~
www/ckout-workflows.md
~
www/co-vs-up.md
~
www/concepts.wiki
~
www/containers.md
~
www/contribute.wiki
~
www/customskin.md
~
www/defcsp.md
~
www/delta_format.wiki
~
www/embeddeddoc.wiki
~
www/env-opts.md
~
www/event.wiki
~
www/fileedit-page.md
~
www/forum.wiki
~
www/fossil-v-git.wiki
~
www/gitusers.md
~
www/globs.md
~
www/glossary.md
~
www/grep.md
~
www/hashes.md
~
www/hashpolicy.wiki
~
www/hints.wiki
~
www/index.wiki
~
www/inout.wiki
~
www/interwiki.md
~
www/javascript.md
~
www/json-api/intro.md
~
www/loadmgmt.md
~
www/makefile.wiki
~
www/mdtest/test1.md
~
www/mirrorlimitations.md
~
www/mirrortogithub.md
~
www/password.wiki
~
www/patchcmd.md
~
www/private.wiki
~
www/quickstart.wiki
~
www/rebaseharm.md
~
www/relatedwork.md
~
www/selfhost.wiki
~
www/server/index.html
~
www/server/windows/service.md
~
www/serverext.wiki
~
www/ssl-server.md
~
www/sync.wiki
~
www/tech_overview.wiki
~
www/th1.md
~
www/unvers.wiki
M
VERSION
+1
-1
| --- VERSION | ||
| +++ VERSION | ||
| @@ -1,1 +1,1 @@ | ||
| 1 | -2.27 | |
| 1 | +2.28 | |
| 2 | 2 |
| --- VERSION | |
| +++ VERSION | |
| @@ -1,1 +1,1 @@ | |
| 1 | 2.27 |
| 2 |
| --- VERSION | |
| +++ VERSION | |
| @@ -1,1 +1,1 @@ | |
| 1 | 2.28 |
| 2 |
+826
-980
| --- extsrc/shell.c | ||
| +++ extsrc/shell.c | ||
| @@ -122,10 +122,13 @@ | ||
| 122 | 122 | typedef sqlite3_int64 i64; |
| 123 | 123 | typedef sqlite3_uint64 u64; |
| 124 | 124 | typedef unsigned char u8; |
| 125 | 125 | #include <ctype.h> |
| 126 | 126 | #include <stdarg.h> |
| 127 | +#ifndef _WIN32 | |
| 128 | +# include <sys/time.h> | |
| 129 | +#endif | |
| 127 | 130 | |
| 128 | 131 | #if !defined(_WIN32) && !defined(WIN32) |
| 129 | 132 | # include <signal.h> |
| 130 | 133 | # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI) |
| 131 | 134 | # include <pwd.h> |
| @@ -646,12 +649,23 @@ | ||
| 646 | 649 | if( a==0 ) a = ""; |
| 647 | 650 | if( b==0 ) b = ""; |
| 648 | 651 | return strncmp(a,b,n); |
| 649 | 652 | } |
| 650 | 653 | |
| 651 | -/* Return the current wall-clock time */ | |
| 654 | +/* Return the current wall-clock time in microseconds since the | |
| 655 | +** Unix epoch (1970-01-01T00:00:00Z) | |
| 656 | +*/ | |
| 652 | 657 | static sqlite3_int64 timeOfDay(void){ |
| 658 | +#if defined(_WIN64) | |
| 659 | + sqlite3_uint64 t; | |
| 660 | + FILETIME tm; | |
| 661 | + GetSystemTimePreciseAsFileTime(&tm); | |
| 662 | + t = ((u64)tm.dwHighDateTime<<32) | (u64)tm.dwLowDateTime; | |
| 663 | + t += 116444736000000000LL; | |
| 664 | + t /= 10; | |
| 665 | + return t; | |
| 666 | +#elif defined(_WIN32) | |
| 653 | 667 | static sqlite3_vfs *clockVfs = 0; |
| 654 | 668 | sqlite3_int64 t; |
| 655 | 669 | if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); |
| 656 | 670 | if( clockVfs==0 ) return 0; /* Never actually happens */ |
| 657 | 671 | if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ |
| @@ -659,11 +673,16 @@ | ||
| 659 | 673 | }else{ |
| 660 | 674 | double r; |
| 661 | 675 | clockVfs->xCurrentTime(clockVfs, &r); |
| 662 | 676 | t = (sqlite3_int64)(r*86400000.0); |
| 663 | 677 | } |
| 664 | - return t; | |
| 678 | + return t*1000; | |
| 679 | +#else | |
| 680 | + struct timeval sNow; | |
| 681 | + (void)gettimeofday(&sNow,0); | |
| 682 | + return ((i64)sNow.tv_sec)*1000000 + sNow.tv_usec; | |
| 683 | +#endif | |
| 665 | 684 | } |
| 666 | 685 | |
| 667 | 686 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) |
| 668 | 687 | #include <sys/time.h> |
| 669 | 688 | #include <sys/resource.h> |
| @@ -704,12 +723,12 @@ | ||
| 704 | 723 | static void endTimer(FILE *out){ |
| 705 | 724 | if( enableTimer ){ |
| 706 | 725 | sqlite3_int64 iEnd = timeOfDay(); |
| 707 | 726 | struct rusage sEnd; |
| 708 | 727 | getrusage(RUSAGE_SELF, &sEnd); |
| 709 | - sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", | |
| 710 | - (iEnd - iBegin)*0.001, | |
| 728 | + sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n", | |
| 729 | + (iEnd - iBegin)*0.000001, | |
| 711 | 730 | timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |
| 712 | 731 | timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
| 713 | 732 | } |
| 714 | 733 | } |
| 715 | 734 | |
| @@ -783,14 +802,23 @@ | ||
| 783 | 802 | static void endTimer(FILE *out){ |
| 784 | 803 | if( enableTimer && getProcessTimesAddr){ |
| 785 | 804 | FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
| 786 | 805 | sqlite3_int64 ftWallEnd = timeOfDay(); |
| 787 | 806 | getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); |
| 788 | - sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", | |
| 789 | - (ftWallEnd - ftWallBegin)*0.001, | |
| 807 | +#ifdef _WIN64 | |
| 808 | + /* microsecond precision on 64-bit windows */ | |
| 809 | + sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n", | |
| 810 | + (ftWallEnd - ftWallBegin)*0.000001, | |
| 811 | + timeDiff(&ftUserBegin, &ftUserEnd), | |
| 812 | + timeDiff(&ftKernelBegin, &ftKernelEnd)); | |
| 813 | +#else | |
| 814 | + /* millisecond precisino on 32-bit windows */ | |
| 815 | + sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n", | |
| 816 | + (ftWallEnd - ftWallBegin)*0.000001, | |
| 790 | 817 | timeDiff(&ftUserBegin, &ftUserEnd), |
| 791 | 818 | timeDiff(&ftKernelBegin, &ftKernelEnd)); |
| 819 | +#endif | |
| 792 | 820 | } |
| 793 | 821 | } |
| 794 | 822 | |
| 795 | 823 | #define BEGIN_TIMER beginTimer() |
| 796 | 824 | #define END_TIMER(X) endTimer(X) |
| @@ -1126,11 +1154,11 @@ | ||
| 1126 | 1154 | } |
| 1127 | 1155 | if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 |
| 1128 | 1156 | && (z[3] & 0xc0)==0x80 |
| 1129 | 1157 | ){ |
| 1130 | 1158 | *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 |
| 1131 | - | (z[4] & 0x3f); | |
| 1159 | + | (z[3] & 0x3f); | |
| 1132 | 1160 | return 4; |
| 1133 | 1161 | } |
| 1134 | 1162 | *pU = 0; |
| 1135 | 1163 | return 1; |
| 1136 | 1164 | } |
| @@ -1189,18 +1217,28 @@ | ||
| 1189 | 1217 | ** since with %*.*s the width is measured in bytes, not characters. |
| 1190 | 1218 | ** |
| 1191 | 1219 | ** Take into account zero-width and double-width Unicode characters. |
| 1192 | 1220 | ** In other words, a zero-width character does not count toward the |
| 1193 | 1221 | ** the w limit. A double-width character counts as two. |
| 1222 | +** | |
| 1223 | +** w should normally be a small number. A couple hundred at most. This | |
| 1224 | +** routine caps w at 100 million to avoid integer overflow issues. | |
| 1194 | 1225 | */ |
| 1195 | 1226 | static void utf8_width_print(FILE *out, int w, const char *zUtf){ |
| 1196 | 1227 | const unsigned char *a = (const unsigned char*)zUtf; |
| 1228 | + static const int mxW = 10000000; | |
| 1197 | 1229 | unsigned char c; |
| 1198 | 1230 | int i = 0; |
| 1199 | 1231 | int n = 0; |
| 1200 | 1232 | int k; |
| 1201 | - int aw = w<0 ? -w : w; | |
| 1233 | + int aw; | |
| 1234 | + if( w<-mxW ){ | |
| 1235 | + w = -mxW; | |
| 1236 | + }else if( w>mxW ){ | |
| 1237 | + w= mxW; | |
| 1238 | + } | |
| 1239 | + aw = w<0 ? -w : w; | |
| 1202 | 1240 | if( zUtf==0 ) zUtf = ""; |
| 1203 | 1241 | while( (c = a[i])!=0 ){ |
| 1204 | 1242 | if( (c&0xc0)==0xc0 ){ |
| 1205 | 1243 | int u; |
| 1206 | 1244 | int len = decodeUtf8(a+i, &u); |
| @@ -1323,11 +1361,11 @@ | ||
| 1323 | 1361 | |
| 1324 | 1362 | /* |
| 1325 | 1363 | ** This routine reads a line of text from FILE in, stores |
| 1326 | 1364 | ** the text in memory obtained from malloc() and returns a pointer |
| 1327 | 1365 | ** to the text. NULL is returned at end of file, or if malloc() |
| 1328 | -** fails. | |
| 1366 | +** fails, or if the length of the line is longer than about a gigabyte. | |
| 1329 | 1367 | ** |
| 1330 | 1368 | ** If zLine is not NULL then it is a malloced buffer returned from |
| 1331 | 1369 | ** a previous call to this routine that may be reused. |
| 1332 | 1370 | */ |
| 1333 | 1371 | static char *local_getline(char *zLine, FILE *in){ |
| @@ -1334,10 +1372,14 @@ | ||
| 1334 | 1372 | int nLine = zLine==0 ? 0 : 100; |
| 1335 | 1373 | int n = 0; |
| 1336 | 1374 | |
| 1337 | 1375 | while( 1 ){ |
| 1338 | 1376 | if( n+100>nLine ){ |
| 1377 | + if( nLine>=1073741773 ){ | |
| 1378 | + free(zLine); | |
| 1379 | + return 0; | |
| 1380 | + } | |
| 1339 | 1381 | nLine = nLine*2 + 100; |
| 1340 | 1382 | zLine = realloc(zLine, nLine); |
| 1341 | 1383 | shell_check_oom(zLine); |
| 1342 | 1384 | } |
| 1343 | 1385 | if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ |
| @@ -1417,14 +1459,18 @@ | ||
| 1417 | 1459 | return -1; |
| 1418 | 1460 | } |
| 1419 | 1461 | |
| 1420 | 1462 | /* |
| 1421 | 1463 | ** Interpret zArg as an integer value, possibly with suffixes. |
| 1464 | +** | |
| 1465 | +** If the value specified by zArg is outside the range of values that | |
| 1466 | +** can be represented using a 64-bit twos-complement integer, then return | |
| 1467 | +** the nearest representable value. | |
| 1422 | 1468 | */ |
| 1423 | 1469 | static sqlite3_int64 integerValue(const char *zArg){ |
| 1424 | - sqlite3_int64 v = 0; | |
| 1425 | - static const struct { char *zSuffix; int iMult; } aMult[] = { | |
| 1470 | + sqlite3_uint64 v = 0; | |
| 1471 | + static const struct { char *zSuffix; unsigned int iMult; } aMult[] = { | |
| 1426 | 1472 | { "KiB", 1024 }, |
| 1427 | 1473 | { "MiB", 1024*1024 }, |
| 1428 | 1474 | { "GiB", 1024*1024*1024 }, |
| 1429 | 1475 | { "KB", 1000 }, |
| 1430 | 1476 | { "MB", 1000000 }, |
| @@ -1443,46 +1489,54 @@ | ||
| 1443 | 1489 | } |
| 1444 | 1490 | if( zArg[0]=='0' && zArg[1]=='x' ){ |
| 1445 | 1491 | int x; |
| 1446 | 1492 | zArg += 2; |
| 1447 | 1493 | while( (x = hexDigitValue(zArg[0]))>=0 ){ |
| 1494 | + if( v > 0x0fffffffffffffffULL ) goto integer_overflow; | |
| 1448 | 1495 | v = (v<<4) + x; |
| 1449 | 1496 | zArg++; |
| 1450 | 1497 | } |
| 1451 | 1498 | }else{ |
| 1452 | 1499 | while( IsDigit(zArg[0]) ){ |
| 1453 | - v = v*10 + zArg[0] - '0'; | |
| 1500 | + if( v>=922337203685477580LL ){ | |
| 1501 | + if( v>922337203685477580LL || zArg[0]>='8' ) goto integer_overflow; | |
| 1502 | + } | |
| 1503 | + v = v*10 + (zArg[0] - '0'); | |
| 1454 | 1504 | zArg++; |
| 1455 | 1505 | } |
| 1456 | 1506 | } |
| 1457 | 1507 | for(i=0; i<ArraySize(aMult); i++){ |
| 1458 | 1508 | if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ |
| 1509 | + if( 0x7fffffffffffffffULL/aMult[i].iMult < v ) goto integer_overflow; | |
| 1459 | 1510 | v *= aMult[i].iMult; |
| 1460 | 1511 | break; |
| 1461 | 1512 | } |
| 1462 | 1513 | } |
| 1463 | - return isNeg? -v : v; | |
| 1514 | + if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow; | |
| 1515 | + return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v; | |
| 1516 | +integer_overflow: | |
| 1517 | + return isNeg ? (i64)0x8000000000000000LL : 0x7fffffffffffffffLL; | |
| 1464 | 1518 | } |
| 1465 | 1519 | |
| 1466 | 1520 | /* |
| 1467 | 1521 | ** A variable length string to which one can append text. |
| 1468 | 1522 | */ |
| 1469 | 1523 | typedef struct ShellText ShellText; |
| 1470 | 1524 | struct ShellText { |
| 1471 | - char *z; | |
| 1472 | - int n; | |
| 1473 | - int nAlloc; | |
| 1525 | + char *zTxt; /* The text */ | |
| 1526 | + i64 n; /* Number of bytes of zTxt[] actually used */ | |
| 1527 | + i64 nAlloc; /* Number of bytes allocated for zTxt[] */ | |
| 1474 | 1528 | }; |
| 1475 | 1529 | |
| 1476 | 1530 | /* |
| 1477 | 1531 | ** Initialize and destroy a ShellText object |
| 1478 | 1532 | */ |
| 1479 | 1533 | static void initText(ShellText *p){ |
| 1480 | 1534 | memset(p, 0, sizeof(*p)); |
| 1481 | 1535 | } |
| 1482 | 1536 | static void freeText(ShellText *p){ |
| 1483 | - free(p->z); | |
| 1537 | + sqlite3_free(p->zTxt); | |
| 1484 | 1538 | initText(p); |
| 1485 | 1539 | } |
| 1486 | 1540 | |
| 1487 | 1541 | /* zIn is either a pointer to a NULL-terminated string in memory obtained |
| 1488 | 1542 | ** from malloc(), or a NULL pointer. The string pointed to by zAppend is |
| @@ -1503,30 +1557,30 @@ | ||
| 1503 | 1557 | for(i=0; i<nAppend; i++){ |
| 1504 | 1558 | if( zAppend[i]==quote ) len++; |
| 1505 | 1559 | } |
| 1506 | 1560 | } |
| 1507 | 1561 | |
| 1508 | - if( p->z==0 || p->n+len>=p->nAlloc ){ | |
| 1562 | + if( p->zTxt==0 || p->n+len>=p->nAlloc ){ | |
| 1509 | 1563 | p->nAlloc = p->nAlloc*2 + len + 20; |
| 1510 | - p->z = realloc(p->z, p->nAlloc); | |
| 1511 | - shell_check_oom(p->z); | |
| 1564 | + p->zTxt = sqlite3_realloc64(p->zTxt, p->nAlloc); | |
| 1565 | + shell_check_oom(p->zTxt); | |
| 1512 | 1566 | } |
| 1513 | 1567 | |
| 1514 | 1568 | if( quote ){ |
| 1515 | - char *zCsr = p->z+p->n; | |
| 1569 | + char *zCsr = p->zTxt+p->n; | |
| 1516 | 1570 | *zCsr++ = quote; |
| 1517 | 1571 | for(i=0; i<nAppend; i++){ |
| 1518 | 1572 | *zCsr++ = zAppend[i]; |
| 1519 | 1573 | if( zAppend[i]==quote ) *zCsr++ = quote; |
| 1520 | 1574 | } |
| 1521 | 1575 | *zCsr++ = quote; |
| 1522 | - p->n = (int)(zCsr - p->z); | |
| 1576 | + p->n = (i64)(zCsr - p->zTxt); | |
| 1523 | 1577 | *zCsr = '\0'; |
| 1524 | 1578 | }else{ |
| 1525 | - memcpy(p->z+p->n, zAppend, nAppend); | |
| 1579 | + memcpy(p->zTxt+p->n, zAppend, nAppend); | |
| 1526 | 1580 | p->n += nAppend; |
| 1527 | - p->z[p->n] = '\0'; | |
| 1581 | + p->zTxt[p->n] = '\0'; | |
| 1528 | 1582 | } |
| 1529 | 1583 | } |
| 1530 | 1584 | |
| 1531 | 1585 | /* |
| 1532 | 1586 | ** Attempt to determine if identifier zName needs to be quoted, either |
| @@ -1547,10 +1601,13 @@ | ||
| 1547 | 1601 | } |
| 1548 | 1602 | |
| 1549 | 1603 | /* |
| 1550 | 1604 | ** Construct a fake object name and column list to describe the structure |
| 1551 | 1605 | ** of the view, virtual table, or table valued function zSchema.zName. |
| 1606 | +** | |
| 1607 | +** The returned string comes from sqlite3_mprintf() and should be freed | |
| 1608 | +** by the caller using sqlite3_free(). | |
| 1552 | 1609 | */ |
| 1553 | 1610 | static char *shellFakeSchema( |
| 1554 | 1611 | sqlite3 *db, /* The database connection containing the vtab */ |
| 1555 | 1612 | const char *zSchema, /* Schema of the database holding the vtab */ |
| 1556 | 1613 | const char *zName /* The name of the virtual table */ |
| @@ -1587,13 +1644,13 @@ | ||
| 1587 | 1644 | } |
| 1588 | 1645 | appendText(&s, ")", 0); |
| 1589 | 1646 | sqlite3_finalize(pStmt); |
| 1590 | 1647 | if( nRow==0 ){ |
| 1591 | 1648 | freeText(&s); |
| 1592 | - s.z = 0; | |
| 1649 | + s.zTxt = 0; | |
| 1593 | 1650 | } |
| 1594 | - return s.z; | |
| 1651 | + return s.zTxt; | |
| 1595 | 1652 | } |
| 1596 | 1653 | |
| 1597 | 1654 | /* |
| 1598 | 1655 | ** SQL function: strtod(X) |
| 1599 | 1656 | ** |
| @@ -1692,11 +1749,11 @@ | ||
| 1692 | 1749 | if( z==0 ){ |
| 1693 | 1750 | z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake); |
| 1694 | 1751 | }else{ |
| 1695 | 1752 | z = sqlite3_mprintf("%z\n/* %s */", z, zFake); |
| 1696 | 1753 | } |
| 1697 | - free(zFake); | |
| 1754 | + sqlite3_free(zFake); | |
| 1698 | 1755 | } |
| 1699 | 1756 | if( z ){ |
| 1700 | 1757 | sqlite3_result_text(pCtx, z, -1, sqlite3_free); |
| 1701 | 1758 | return; |
| 1702 | 1759 | } |
| @@ -3667,11 +3724,12 @@ | ||
| 3667 | 3724 | iExp -= p->nFrac; |
| 3668 | 3725 | p->nFrac = 0; |
| 3669 | 3726 | } |
| 3670 | 3727 | } |
| 3671 | 3728 | if( iExp>0 ){ |
| 3672 | - p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); | |
| 3729 | + p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit | |
| 3730 | + + (sqlite3_int64)iExp + 1 ); | |
| 3673 | 3731 | if( p->a==0 ) goto new_from_text_failed; |
| 3674 | 3732 | memset(p->a+p->nDigit, 0, iExp); |
| 3675 | 3733 | p->nDigit += iExp; |
| 3676 | 3734 | } |
| 3677 | 3735 | }else if( iExp<0 ){ |
| @@ -3686,18 +3744,23 @@ | ||
| 3686 | 3744 | iExp -= nExtra; |
| 3687 | 3745 | p->nFrac = p->nDigit - 1; |
| 3688 | 3746 | } |
| 3689 | 3747 | } |
| 3690 | 3748 | if( iExp>0 ){ |
| 3691 | - p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); | |
| 3749 | + p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit | |
| 3750 | + + (sqlite3_int64)iExp + 1 ); | |
| 3692 | 3751 | if( p->a==0 ) goto new_from_text_failed; |
| 3693 | 3752 | memmove(p->a+iExp, p->a, p->nDigit); |
| 3694 | 3753 | memset(p->a, 0, iExp); |
| 3695 | 3754 | p->nDigit += iExp; |
| 3696 | 3755 | p->nFrac += iExp; |
| 3697 | 3756 | } |
| 3698 | 3757 | } |
| 3758 | + if( p->sign ){ | |
| 3759 | + for(i=0; i<p->nDigit && p->a[i]==0; i++){} | |
| 3760 | + if( i>=p->nDigit ) p->sign = 0; | |
| 3761 | + } | |
| 3699 | 3762 | return p; |
| 3700 | 3763 | |
| 3701 | 3764 | new_from_text_failed: |
| 3702 | 3765 | if( p ){ |
| 3703 | 3766 | if( p->a ) sqlite3_free(p->a); |
| @@ -3786,11 +3849,11 @@ | ||
| 3786 | 3849 | } |
| 3787 | 3850 | if( p->isNull ){ |
| 3788 | 3851 | sqlite3_result_null(pCtx); |
| 3789 | 3852 | return; |
| 3790 | 3853 | } |
| 3791 | - z = sqlite3_malloc( p->nDigit+4 ); | |
| 3854 | + z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+4 ); | |
| 3792 | 3855 | if( z==0 ){ |
| 3793 | 3856 | sqlite3_result_error_nomem(pCtx); |
| 3794 | 3857 | return; |
| 3795 | 3858 | } |
| 3796 | 3859 | i = 0; |
| @@ -3851,11 +3914,11 @@ | ||
| 3851 | 3914 | } |
| 3852 | 3915 | for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){} |
| 3853 | 3916 | for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){} |
| 3854 | 3917 | nFrac = p->nFrac + (nDigit - p->nDigit); |
| 3855 | 3918 | nDigit -= nZero; |
| 3856 | - z = sqlite3_malloc( nDigit+20 ); | |
| 3919 | + z = sqlite3_malloc64( (sqlite3_int64)nDigit+20 ); | |
| 3857 | 3920 | if( z==0 ){ |
| 3858 | 3921 | sqlite3_result_error_nomem(pCtx); |
| 3859 | 3922 | return; |
| 3860 | 3923 | } |
| 3861 | 3924 | if( nDigit==0 ){ |
| @@ -3896,17 +3959,25 @@ | ||
| 3896 | 3959 | ** pA!=0 |
| 3897 | 3960 | ** pA->isNull==0 |
| 3898 | 3961 | ** pB!=0 |
| 3899 | 3962 | ** pB->isNull==0 |
| 3900 | 3963 | */ |
| 3901 | -static int decimal_cmp(const Decimal *pA, const Decimal *pB){ | |
| 3964 | +static int decimal_cmp(Decimal *pA, Decimal *pB){ | |
| 3902 | 3965 | int nASig, nBSig, rc, n; |
| 3966 | + while( pA->nFrac>0 && pA->a[pA->nDigit-1]==0 ){ | |
| 3967 | + pA->nDigit--; | |
| 3968 | + pA->nFrac--; | |
| 3969 | + } | |
| 3970 | + while( pB->nFrac>0 && pB->a[pB->nDigit-1]==0 ){ | |
| 3971 | + pB->nDigit--; | |
| 3972 | + pB->nFrac--; | |
| 3973 | + } | |
| 3903 | 3974 | if( pA->sign!=pB->sign ){ |
| 3904 | 3975 | return pA->sign ? -1 : +1; |
| 3905 | 3976 | } |
| 3906 | 3977 | if( pA->sign ){ |
| 3907 | - const Decimal *pTemp = pA; | |
| 3978 | + Decimal *pTemp = pA; | |
| 3908 | 3979 | pA = pB; |
| 3909 | 3980 | pB = pTemp; |
| 3910 | 3981 | } |
| 3911 | 3982 | nASig = pA->nDigit - pA->nFrac; |
| 3912 | 3983 | nBSig = pB->nDigit - pB->nFrac; |
| @@ -4064,11 +4135,12 @@ | ||
| 4064 | 4135 | if( pA==0 || pA->oom || pA->isNull |
| 4065 | 4136 | || pB==0 || pB->oom || pB->isNull |
| 4066 | 4137 | ){ |
| 4067 | 4138 | goto mul_end; |
| 4068 | 4139 | } |
| 4069 | - acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 ); | |
| 4140 | + acc = sqlite3_malloc64( (sqlite3_int64)pA->nDigit + | |
| 4141 | + (sqlite3_int64)pB->nDigit + 2 ); | |
| 4070 | 4142 | if( acc==0 ){ |
| 4071 | 4143 | pA->oom = 1; |
| 4072 | 4144 | goto mul_end; |
| 4073 | 4145 | } |
| 4074 | 4146 | memset(acc, 0, pA->nDigit + pB->nDigit + 2); |
| @@ -4151,11 +4223,11 @@ | ||
| 4151 | 4223 | r = -r; |
| 4152 | 4224 | }else{ |
| 4153 | 4225 | isNeg = 0; |
| 4154 | 4226 | } |
| 4155 | 4227 | memcpy(&a,&r,sizeof(a)); |
| 4156 | - if( a==0 ){ | |
| 4228 | + if( a==0 || a==(sqlite3_int64)0x8000000000000000LL){ | |
| 4157 | 4229 | e = 0; |
| 4158 | 4230 | m = 0; |
| 4159 | 4231 | }else{ |
| 4160 | 4232 | e = a>>52; |
| 4161 | 4233 | m = a & ((((sqlite3_int64)1)<<52)-1); |
| @@ -4426,516 +4498,10 @@ | ||
| 4426 | 4498 | } |
| 4427 | 4499 | return rc; |
| 4428 | 4500 | } |
| 4429 | 4501 | |
| 4430 | 4502 | /************************* End ../ext/misc/decimal.c ********************/ |
| 4431 | -/************************* Begin ../ext/misc/percentile.c ******************/ | |
| 4432 | -/* | |
| 4433 | -** 2013-05-28 | |
| 4434 | -** | |
| 4435 | -** The author disclaims copyright to this source code. In place of | |
| 4436 | -** a legal notice, here is a blessing: | |
| 4437 | -** | |
| 4438 | -** May you do good and not evil. | |
| 4439 | -** May you find forgiveness for yourself and forgive others. | |
| 4440 | -** May you share freely, never taking more than you give. | |
| 4441 | -** | |
| 4442 | -****************************************************************************** | |
| 4443 | -** | |
| 4444 | -** This file contains code to implement the percentile(Y,P) SQL function | |
| 4445 | -** and similar as described below: | |
| 4446 | -** | |
| 4447 | -** (1) The percentile(Y,P) function is an aggregate function taking | |
| 4448 | -** exactly two arguments. | |
| 4449 | -** | |
| 4450 | -** (2) If the P argument to percentile(Y,P) is not the same for every | |
| 4451 | -** row in the aggregate then an error is thrown. The word "same" | |
| 4452 | -** in the previous sentence means that the value differ by less | |
| 4453 | -** than 0.001. | |
| 4454 | -** | |
| 4455 | -** (3) If the P argument to percentile(Y,P) evaluates to anything other | |
| 4456 | -** than a number in the range of 0.0 to 100.0 inclusive then an | |
| 4457 | -** error is thrown. | |
| 4458 | -** | |
| 4459 | -** (4) If any Y argument to percentile(Y,P) evaluates to a value that | |
| 4460 | -** is not NULL and is not numeric then an error is thrown. | |
| 4461 | -** | |
| 4462 | -** (5) If any Y argument to percentile(Y,P) evaluates to plus or minus | |
| 4463 | -** infinity then an error is thrown. (SQLite always interprets NaN | |
| 4464 | -** values as NULL.) | |
| 4465 | -** | |
| 4466 | -** (6) Both Y and P in percentile(Y,P) can be arbitrary expressions, | |
| 4467 | -** including CASE WHEN expressions. | |
| 4468 | -** | |
| 4469 | -** (7) The percentile(Y,P) aggregate is able to handle inputs of at least | |
| 4470 | -** one million (1,000,000) rows. | |
| 4471 | -** | |
| 4472 | -** (8) If there are no non-NULL values for Y, then percentile(Y,P) | |
| 4473 | -** returns NULL. | |
| 4474 | -** | |
| 4475 | -** (9) If there is exactly one non-NULL value for Y, the percentile(Y,P) | |
| 4476 | -** returns the one Y value. | |
| 4477 | -** | |
| 4478 | -** (10) If there N non-NULL values of Y where N is two or more and | |
| 4479 | -** the Y values are ordered from least to greatest and a graph is | |
| 4480 | -** drawn from 0 to N-1 such that the height of the graph at J is | |
| 4481 | -** the J-th Y value and such that straight lines are drawn between | |
| 4482 | -** adjacent Y values, then the percentile(Y,P) function returns | |
| 4483 | -** the height of the graph at P*(N-1)/100. | |
| 4484 | -** | |
| 4485 | -** (11) The percentile(Y,P) function always returns either a floating | |
| 4486 | -** point number or NULL. | |
| 4487 | -** | |
| 4488 | -** (12) The percentile(Y,P) is implemented as a single C99 source-code | |
| 4489 | -** file that compiles into a shared-library or DLL that can be loaded | |
| 4490 | -** into SQLite using the sqlite3_load_extension() interface. | |
| 4491 | -** | |
| 4492 | -** (13) A separate median(Y) function is the equivalent percentile(Y,50). | |
| 4493 | -** | |
| 4494 | -** (14) A separate percentile_cont(Y,P) function is equivalent to | |
| 4495 | -** percentile(Y,P/100.0). In other words, the fraction value in | |
| 4496 | -** the second argument is in the range of 0 to 1 instead of 0 to 100. | |
| 4497 | -** | |
| 4498 | -** (15) A separate percentile_disc(Y,P) function is like | |
| 4499 | -** percentile_cont(Y,P) except that instead of returning the weighted | |
| 4500 | -** average of the nearest two input values, it returns the next lower | |
| 4501 | -** value. So the percentile_disc(Y,P) will always return a value | |
| 4502 | -** that was one of the inputs. | |
| 4503 | -** | |
| 4504 | -** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and | |
| 4505 | -** percentile_disc(Y,P) can be used as window functions. | |
| 4506 | -** | |
| 4507 | -** Differences from standard SQL: | |
| 4508 | -** | |
| 4509 | -** * The percentile_cont(X,P) function is equivalent to the following in | |
| 4510 | -** standard SQL: | |
| 4511 | -** | |
| 4512 | -** (percentile_cont(P) WITHIN GROUP (ORDER BY X)) | |
| 4513 | -** | |
| 4514 | -** The SQLite syntax is much more compact. The standard SQL syntax | |
| 4515 | -** is also supported if SQLite is compiled with the | |
| 4516 | -** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option. | |
| 4517 | -** | |
| 4518 | -** * No median(X) function exists in the SQL standard. App developers | |
| 4519 | -** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)". | |
| 4520 | -** | |
| 4521 | -** * No percentile(Y,P) function exists in the SQL standard. Instead of | |
| 4522 | -** percential(Y,P), developers must write this: | |
| 4523 | -** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that | |
| 4524 | -** the fraction parameter to percentile() goes from 0 to 100 whereas | |
| 4525 | -** the fraction parameter in SQL standard percentile_cont() goes from | |
| 4526 | -** 0 to 1. | |
| 4527 | -** | |
| 4528 | -** Implementation notes as of 2024-08-31: | |
| 4529 | -** | |
| 4530 | -** * The regular aggregate-function versions of these routines work | |
| 4531 | -** by accumulating all values in an array of doubles, then sorting | |
| 4532 | -** that array using quicksort before computing the answer. Thus | |
| 4533 | -** the runtime is O(NlogN) where N is the number of rows of input. | |
| 4534 | -** | |
| 4535 | -** * For the window-function versions of these routines, the array of | |
| 4536 | -** inputs is sorted as soon as the first value is computed. Thereafter, | |
| 4537 | -** the array is kept in sorted order using an insert-sort. This | |
| 4538 | -** results in O(N*K) performance where K is the size of the window. | |
| 4539 | -** One can imagine alternative implementations that give O(N*logN*logK) | |
| 4540 | -** performance, but they require more complex logic and data structures. | |
| 4541 | -** The developers have elected to keep the asymptotically slower | |
| 4542 | -** algorithm for now, for simplicity, under the theory that window | |
| 4543 | -** functions are seldom used and when they are, the window size K is | |
| 4544 | -** often small. The developers might revisit that decision later, | |
| 4545 | -** should the need arise. | |
| 4546 | -*/ | |
| 4547 | -#if defined(SQLITE3_H) | |
| 4548 | - /* no-op */ | |
| 4549 | -#elif defined(SQLITE_STATIC_PERCENTILE) | |
| 4550 | -/* # include "sqlite3.h" */ | |
| 4551 | -#else | |
| 4552 | -/* # include "sqlite3ext.h" */ | |
| 4553 | - SQLITE_EXTENSION_INIT1 | |
| 4554 | -#endif | |
| 4555 | -#include <assert.h> | |
| 4556 | -#include <string.h> | |
| 4557 | -#include <stdlib.h> | |
| 4558 | - | |
| 4559 | -/* The following object is the group context for a single percentile() | |
| 4560 | -** aggregate. Remember all input Y values until the very end. | |
| 4561 | -** Those values are accumulated in the Percentile.a[] array. | |
| 4562 | -*/ | |
| 4563 | -typedef struct Percentile Percentile; | |
| 4564 | -struct Percentile { | |
| 4565 | - unsigned nAlloc; /* Number of slots allocated for a[] */ | |
| 4566 | - unsigned nUsed; /* Number of slots actually used in a[] */ | |
| 4567 | - char bSorted; /* True if a[] is already in sorted order */ | |
| 4568 | - char bKeepSorted; /* True if advantageous to keep a[] sorted */ | |
| 4569 | - char bPctValid; /* True if rPct is valid */ | |
| 4570 | - double rPct; /* Fraction. 0.0 to 1.0 */ | |
| 4571 | - double *a; /* Array of Y values */ | |
| 4572 | -}; | |
| 4573 | - | |
| 4574 | -/* Details of each function in the percentile family */ | |
| 4575 | -typedef struct PercentileFunc PercentileFunc; | |
| 4576 | -struct PercentileFunc { | |
| 4577 | - const char *zName; /* Function name */ | |
| 4578 | - char nArg; /* Number of arguments */ | |
| 4579 | - char mxFrac; /* Maximum value of the "fraction" input */ | |
| 4580 | - char bDiscrete; /* True for percentile_disc() */ | |
| 4581 | -}; | |
| 4582 | -static const PercentileFunc aPercentFunc[] = { | |
| 4583 | - { "median", 1, 1, 0 }, | |
| 4584 | - { "percentile", 2, 100, 0 }, | |
| 4585 | - { "percentile_cont", 2, 1, 0 }, | |
| 4586 | - { "percentile_disc", 2, 1, 1 }, | |
| 4587 | -}; | |
| 4588 | - | |
| 4589 | -/* | |
| 4590 | -** Return TRUE if the input floating-point number is an infinity. | |
| 4591 | -*/ | |
| 4592 | -static int percentIsInfinity(double r){ | |
| 4593 | - sqlite3_uint64 u; | |
| 4594 | - assert( sizeof(u)==sizeof(r) ); | |
| 4595 | - memcpy(&u, &r, sizeof(u)); | |
| 4596 | - return ((u>>52)&0x7ff)==0x7ff; | |
| 4597 | -} | |
| 4598 | - | |
| 4599 | -/* | |
| 4600 | -** Return TRUE if two doubles differ by 0.001 or less. | |
| 4601 | -*/ | |
| 4602 | -static int percentSameValue(double a, double b){ | |
| 4603 | - a -= b; | |
| 4604 | - return a>=-0.001 && a<=0.001; | |
| 4605 | -} | |
| 4606 | - | |
| 4607 | -/* | |
| 4608 | -** Search p (which must have p->bSorted) looking for an entry with | |
| 4609 | -** value y. Return the index of that entry. | |
| 4610 | -** | |
| 4611 | -** If bExact is true, return -1 if the entry is not found. | |
| 4612 | -** | |
| 4613 | -** If bExact is false, return the index at which a new entry with | |
| 4614 | -** value y should be insert in order to keep the values in sorted | |
| 4615 | -** order. The smallest return value in this case will be 0, and | |
| 4616 | -** the largest return value will be p->nUsed. | |
| 4617 | -*/ | |
| 4618 | -static int percentBinarySearch(Percentile *p, double y, int bExact){ | |
| 4619 | - int iFirst = 0; /* First element of search range */ | |
| 4620 | - int iLast = p->nUsed - 1; /* Last element of search range */ | |
| 4621 | - while( iLast>=iFirst ){ | |
| 4622 | - int iMid = (iFirst+iLast)/2; | |
| 4623 | - double x = p->a[iMid]; | |
| 4624 | - if( x<y ){ | |
| 4625 | - iFirst = iMid + 1; | |
| 4626 | - }else if( x>y ){ | |
| 4627 | - iLast = iMid - 1; | |
| 4628 | - }else{ | |
| 4629 | - return iMid; | |
| 4630 | - } | |
| 4631 | - } | |
| 4632 | - if( bExact ) return -1; | |
| 4633 | - return iFirst; | |
| 4634 | -} | |
| 4635 | - | |
| 4636 | -/* | |
| 4637 | -** Generate an error for a percentile function. | |
| 4638 | -** | |
| 4639 | -** The error format string must have exactly one occurrence of "%%s()" | |
| 4640 | -** (with two '%' characters). That substring will be replaced by the name | |
| 4641 | -** of the function. | |
| 4642 | -*/ | |
| 4643 | -static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ | |
| 4644 | - PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); | |
| 4645 | - char *zMsg1; | |
| 4646 | - char *zMsg2; | |
| 4647 | - va_list ap; | |
| 4648 | - | |
| 4649 | - va_start(ap, zFormat); | |
| 4650 | - zMsg1 = sqlite3_vmprintf(zFormat, ap); | |
| 4651 | - va_end(ap); | |
| 4652 | - zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0; | |
| 4653 | - sqlite3_result_error(pCtx, zMsg2, -1); | |
| 4654 | - sqlite3_free(zMsg1); | |
| 4655 | - sqlite3_free(zMsg2); | |
| 4656 | -} | |
| 4657 | - | |
| 4658 | -/* | |
| 4659 | -** The "step" function for percentile(Y,P) is called once for each | |
| 4660 | -** input row. | |
| 4661 | -*/ | |
| 4662 | -static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ | |
| 4663 | - Percentile *p; | |
| 4664 | - double rPct; | |
| 4665 | - int eType; | |
| 4666 | - double y; | |
| 4667 | - assert( argc==2 || argc==1 ); | |
| 4668 | - | |
| 4669 | - if( argc==1 ){ | |
| 4670 | - /* Requirement 13: median(Y) is the same as percentile(Y,50). */ | |
| 4671 | - rPct = 0.5; | |
| 4672 | - }else{ | |
| 4673 | - /* Requirement 3: P must be a number between 0 and 100 */ | |
| 4674 | - PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); | |
| 4675 | - eType = sqlite3_value_numeric_type(argv[1]); | |
| 4676 | - rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac; | |
| 4677 | - if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) | |
| 4678 | - || rPct<0.0 || rPct>1.0 | |
| 4679 | - ){ | |
| 4680 | - percentError(pCtx, "the fraction argument to %%s()" | |
| 4681 | - " is not between 0.0 and %.1f", | |
| 4682 | - (double)pFunc->mxFrac); | |
| 4683 | - return; | |
| 4684 | - } | |
| 4685 | - } | |
| 4686 | - | |
| 4687 | - /* Allocate the session context. */ | |
| 4688 | - p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); | |
| 4689 | - if( p==0 ) return; | |
| 4690 | - | |
| 4691 | - /* Remember the P value. Throw an error if the P value is different | |
| 4692 | - ** from any prior row, per Requirement (2). */ | |
| 4693 | - if( !p->bPctValid ){ | |
| 4694 | - p->rPct = rPct; | |
| 4695 | - p->bPctValid = 1; | |
| 4696 | - }else if( !percentSameValue(p->rPct,rPct) ){ | |
| 4697 | - percentError(pCtx, "the fraction argument to %%s()" | |
| 4698 | - " is not the same for all input rows"); | |
| 4699 | - return; | |
| 4700 | - } | |
| 4701 | - | |
| 4702 | - /* Ignore rows for which Y is NULL */ | |
| 4703 | - eType = sqlite3_value_type(argv[0]); | |
| 4704 | - if( eType==SQLITE_NULL ) return; | |
| 4705 | - | |
| 4706 | - /* If not NULL, then Y must be numeric. Otherwise throw an error. | |
| 4707 | - ** Requirement 4 */ | |
| 4708 | - if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ | |
| 4709 | - percentError(pCtx, "input to %%s() is not numeric"); | |
| 4710 | - return; | |
| 4711 | - } | |
| 4712 | - | |
| 4713 | - /* Throw an error if the Y value is infinity or NaN */ | |
| 4714 | - y = sqlite3_value_double(argv[0]); | |
| 4715 | - if( percentIsInfinity(y) ){ | |
| 4716 | - percentError(pCtx, "Inf input to %%s()"); | |
| 4717 | - return; | |
| 4718 | - } | |
| 4719 | - | |
| 4720 | - /* Allocate and store the Y */ | |
| 4721 | - if( p->nUsed>=p->nAlloc ){ | |
| 4722 | - unsigned n = p->nAlloc*2 + 250; | |
| 4723 | - double *a = sqlite3_realloc64(p->a, sizeof(double)*n); | |
| 4724 | - if( a==0 ){ | |
| 4725 | - sqlite3_free(p->a); | |
| 4726 | - memset(p, 0, sizeof(*p)); | |
| 4727 | - sqlite3_result_error_nomem(pCtx); | |
| 4728 | - return; | |
| 4729 | - } | |
| 4730 | - p->nAlloc = n; | |
| 4731 | - p->a = a; | |
| 4732 | - } | |
| 4733 | - if( p->nUsed==0 ){ | |
| 4734 | - p->a[p->nUsed++] = y; | |
| 4735 | - p->bSorted = 1; | |
| 4736 | - }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){ | |
| 4737 | - p->a[p->nUsed++] = y; | |
| 4738 | - }else if( p->bKeepSorted ){ | |
| 4739 | - int i; | |
| 4740 | - i = percentBinarySearch(p, y, 0); | |
| 4741 | - if( i<(int)p->nUsed ){ | |
| 4742 | - memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0])); | |
| 4743 | - } | |
| 4744 | - p->a[i] = y; | |
| 4745 | - p->nUsed++; | |
| 4746 | - }else{ | |
| 4747 | - p->a[p->nUsed++] = y; | |
| 4748 | - p->bSorted = 0; | |
| 4749 | - } | |
| 4750 | -} | |
| 4751 | - | |
| 4752 | -/* | |
| 4753 | -** Interchange two doubles. | |
| 4754 | -*/ | |
| 4755 | -#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} | |
| 4756 | - | |
| 4757 | -/* | |
| 4758 | -** Sort an array of doubles. | |
| 4759 | -** | |
| 4760 | -** Algorithm: quicksort | |
| 4761 | -** | |
| 4762 | -** This is implemented separately rather than using the qsort() routine | |
| 4763 | -** from the standard library because: | |
| 4764 | -** | |
| 4765 | -** (1) To avoid a dependency on qsort() | |
| 4766 | -** (2) To avoid the function call to the comparison routine for each | |
| 4767 | -** comparison. | |
| 4768 | -*/ | |
| 4769 | -static void percentSort(double *a, unsigned int n){ | |
| 4770 | - int iLt; /* Entries before a[iLt] are less than rPivot */ | |
| 4771 | - int iGt; /* Entries at or after a[iGt] are greater than rPivot */ | |
| 4772 | - int i; /* Loop counter */ | |
| 4773 | - double rPivot; /* The pivot value */ | |
| 4774 | - | |
| 4775 | - assert( n>=2 ); | |
| 4776 | - if( a[0]>a[n-1] ){ | |
| 4777 | - SWAP_DOUBLE(a[0],a[n-1]) | |
| 4778 | - } | |
| 4779 | - if( n==2 ) return; | |
| 4780 | - iGt = n-1; | |
| 4781 | - i = n/2; | |
| 4782 | - if( a[0]>a[i] ){ | |
| 4783 | - SWAP_DOUBLE(a[0],a[i]) | |
| 4784 | - }else if( a[i]>a[iGt] ){ | |
| 4785 | - SWAP_DOUBLE(a[i],a[iGt]) | |
| 4786 | - } | |
| 4787 | - if( n==3 ) return; | |
| 4788 | - rPivot = a[i]; | |
| 4789 | - iLt = i = 1; | |
| 4790 | - do{ | |
| 4791 | - if( a[i]<rPivot ){ | |
| 4792 | - if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt]) | |
| 4793 | - iLt++; | |
| 4794 | - i++; | |
| 4795 | - }else if( a[i]>rPivot ){ | |
| 4796 | - do{ | |
| 4797 | - iGt--; | |
| 4798 | - }while( iGt>i && a[iGt]>rPivot ); | |
| 4799 | - SWAP_DOUBLE(a[i],a[iGt]) | |
| 4800 | - }else{ | |
| 4801 | - i++; | |
| 4802 | - } | |
| 4803 | - }while( i<iGt ); | |
| 4804 | - if( iLt>=2 ) percentSort(a, iLt); | |
| 4805 | - if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); | |
| 4806 | - | |
| 4807 | -/* Uncomment for testing */ | |
| 4808 | -#if 0 | |
| 4809 | - for(i=0; i<n-1; i++){ | |
| 4810 | - assert( a[i]<=a[i+1] ); | |
| 4811 | - } | |
| 4812 | -#endif | |
| 4813 | -} | |
| 4814 | - | |
| 4815 | - | |
| 4816 | -/* | |
| 4817 | -** The "inverse" function for percentile(Y,P) is called to remove a | |
| 4818 | -** row that was previously inserted by "step". | |
| 4819 | -*/ | |
| 4820 | -static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){ | |
| 4821 | - Percentile *p; | |
| 4822 | - int eType; | |
| 4823 | - double y; | |
| 4824 | - int i; | |
| 4825 | - assert( argc==2 || argc==1 ); | |
| 4826 | - | |
| 4827 | - /* Allocate the session context. */ | |
| 4828 | - p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); | |
| 4829 | - assert( p!=0 ); | |
| 4830 | - | |
| 4831 | - /* Ignore rows for which Y is NULL */ | |
| 4832 | - eType = sqlite3_value_type(argv[0]); | |
| 4833 | - if( eType==SQLITE_NULL ) return; | |
| 4834 | - | |
| 4835 | - /* If not NULL, then Y must be numeric. Otherwise throw an error. | |
| 4836 | - ** Requirement 4 */ | |
| 4837 | - if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ | |
| 4838 | - return; | |
| 4839 | - } | |
| 4840 | - | |
| 4841 | - /* Ignore the Y value if it is infinity or NaN */ | |
| 4842 | - y = sqlite3_value_double(argv[0]); | |
| 4843 | - if( percentIsInfinity(y) ){ | |
| 4844 | - return; | |
| 4845 | - } | |
| 4846 | - if( p->bSorted==0 ){ | |
| 4847 | - assert( p->nUsed>1 ); | |
| 4848 | - percentSort(p->a, p->nUsed); | |
| 4849 | - p->bSorted = 1; | |
| 4850 | - } | |
| 4851 | - p->bKeepSorted = 1; | |
| 4852 | - | |
| 4853 | - /* Find and remove the row */ | |
| 4854 | - i = percentBinarySearch(p, y, 1); | |
| 4855 | - if( i>=0 ){ | |
| 4856 | - p->nUsed--; | |
| 4857 | - if( i<(int)p->nUsed ){ | |
| 4858 | - memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0])); | |
| 4859 | - } | |
| 4860 | - } | |
| 4861 | -} | |
| 4862 | - | |
| 4863 | -/* | |
| 4864 | -** Compute the final output of percentile(). Clean up all allocated | |
| 4865 | -** memory if and only if bIsFinal is true. | |
| 4866 | -*/ | |
| 4867 | -static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ | |
| 4868 | - Percentile *p; | |
| 4869 | - PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); | |
| 4870 | - unsigned i1, i2; | |
| 4871 | - double v1, v2; | |
| 4872 | - double ix, vx; | |
| 4873 | - p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); | |
| 4874 | - if( p==0 ) return; | |
| 4875 | - if( p->a==0 ) return; | |
| 4876 | - if( p->nUsed ){ | |
| 4877 | - if( p->bSorted==0 ){ | |
| 4878 | - assert( p->nUsed>1 ); | |
| 4879 | - percentSort(p->a, p->nUsed); | |
| 4880 | - p->bSorted = 1; | |
| 4881 | - } | |
| 4882 | - ix = p->rPct*(p->nUsed-1); | |
| 4883 | - i1 = (unsigned)ix; | |
| 4884 | - if( pFunc->bDiscrete ){ | |
| 4885 | - vx = p->a[i1]; | |
| 4886 | - }else{ | |
| 4887 | - i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; | |
| 4888 | - v1 = p->a[i1]; | |
| 4889 | - v2 = p->a[i2]; | |
| 4890 | - vx = v1 + (v2-v1)*(ix-i1); | |
| 4891 | - } | |
| 4892 | - sqlite3_result_double(pCtx, vx); | |
| 4893 | - } | |
| 4894 | - if( bIsFinal ){ | |
| 4895 | - sqlite3_free(p->a); | |
| 4896 | - memset(p, 0, sizeof(*p)); | |
| 4897 | - }else{ | |
| 4898 | - p->bKeepSorted = 1; | |
| 4899 | - } | |
| 4900 | -} | |
| 4901 | -static void percentFinal(sqlite3_context *pCtx){ | |
| 4902 | - percentCompute(pCtx, 1); | |
| 4903 | -} | |
| 4904 | -static void percentValue(sqlite3_context *pCtx){ | |
| 4905 | - percentCompute(pCtx, 0); | |
| 4906 | -} | |
| 4907 | - | |
| 4908 | -#if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE) | |
| 4909 | - | |
| 4910 | -#endif | |
| 4911 | -int sqlite3_percentile_init( | |
| 4912 | - sqlite3 *db, | |
| 4913 | - char **pzErrMsg, | |
| 4914 | - const sqlite3_api_routines *pApi | |
| 4915 | -){ | |
| 4916 | - int rc = SQLITE_OK; | |
| 4917 | - unsigned int i; | |
| 4918 | -#ifdef SQLITE3EXT_H | |
| 4919 | - SQLITE_EXTENSION_INIT2(pApi); | |
| 4920 | -#else | |
| 4921 | - (void)pApi; /* Unused parameter */ | |
| 4922 | -#endif | |
| 4923 | - (void)pzErrMsg; /* Unused parameter */ | |
| 4924 | - for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){ | |
| 4925 | - rc = sqlite3_create_window_function(db, | |
| 4926 | - aPercentFunc[i].zName, | |
| 4927 | - aPercentFunc[i].nArg, | |
| 4928 | - SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1, | |
| 4929 | - (void*)&aPercentFunc[i], | |
| 4930 | - percentStep, percentFinal, percentValue, percentInverse, 0); | |
| 4931 | - if( rc ) break; | |
| 4932 | - } | |
| 4933 | - return rc; | |
| 4934 | -} | |
| 4935 | - | |
| 4936 | -/************************* End ../ext/misc/percentile.c ********************/ | |
| 4937 | 4503 | #undef sqlite3_base_init |
| 4938 | 4504 | #define sqlite3_base_init sqlite3_base64_init |
| 4939 | 4505 | /************************* Begin ../ext/misc/base64.c ******************/ |
| 4940 | 4506 | /* |
| 4941 | 4507 | ** 2022-11-18 |
| @@ -5144,20 +4710,22 @@ | ||
| 5144 | 4710 | return pOut; |
| 5145 | 4711 | } |
| 5146 | 4712 | |
| 5147 | 4713 | /* This function does the work for the SQLite base64(x) UDF. */ |
| 5148 | 4714 | static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){ |
| 5149 | - int nb, nc, nv = sqlite3_value_bytes(av[0]); | |
| 4715 | + sqlite3_int64 nb; | |
| 4716 | + sqlite3_int64 nv = sqlite3_value_bytes(av[0]); | |
| 4717 | + sqlite3_int64 nc; | |
| 5150 | 4718 | int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), |
| 5151 | 4719 | SQLITE_LIMIT_LENGTH, -1); |
| 5152 | 4720 | char *cBuf; |
| 5153 | 4721 | u8 *bBuf; |
| 5154 | 4722 | assert(na==1); |
| 5155 | 4723 | switch( sqlite3_value_type(av[0]) ){ |
| 5156 | 4724 | case SQLITE_BLOB: |
| 5157 | 4725 | nb = nv; |
| 5158 | - nc = 4*(nv+2/3); /* quads needed */ | |
| 4726 | + nc = 4*((nv+2)/3); /* quads needed */ | |
| 5159 | 4727 | nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */ |
| 5160 | 4728 | if( nvMax < nc ){ |
| 5161 | 4729 | sqlite3_result_error(context, "blob expanded to base64 too big", -1); |
| 5162 | 4730 | return; |
| 5163 | 4731 | } |
| @@ -5524,11 +5092,11 @@ | ||
| 5524 | 5092 | } |
| 5525 | 5093 | # endif |
| 5526 | 5094 | |
| 5527 | 5095 | /* This function does the work for the SQLite base85(x) UDF. */ |
| 5528 | 5096 | static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){ |
| 5529 | - int nb, nc, nv = sqlite3_value_bytes(av[0]); | |
| 5097 | + sqlite3_int64 nb, nc, nv = sqlite3_value_bytes(av[0]); | |
| 5530 | 5098 | int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), |
| 5531 | 5099 | SQLITE_LIMIT_LENGTH, -1); |
| 5532 | 5100 | char *cBuf; |
| 5533 | 5101 | u8 *bBuf; |
| 5534 | 5102 | assert(na==1); |
| @@ -5829,10 +5397,13 @@ | ||
| 5829 | 5397 | } |
| 5830 | 5398 | memcpy(&a,&r,sizeof(a)); |
| 5831 | 5399 | if( a==0 ){ |
| 5832 | 5400 | e = 0; |
| 5833 | 5401 | m = 0; |
| 5402 | + }else if( a==(sqlite3_int64)0x8000000000000000LL ){ | |
| 5403 | + e = -1996; | |
| 5404 | + m = -1; | |
| 5834 | 5405 | }else{ |
| 5835 | 5406 | e = a>>52; |
| 5836 | 5407 | m = a & ((((sqlite3_int64)1)<<52)-1); |
| 5837 | 5408 | if( e==0 ){ |
| 5838 | 5409 | m <<= 1; |
| @@ -6052,23 +5623,24 @@ | ||
| 6052 | 5623 | ** Examples: |
| 6053 | 5624 | ** |
| 6054 | 5625 | ** SELECT * FROM generate_series(0,100,5); |
| 6055 | 5626 | ** |
| 6056 | 5627 | ** The query above returns integers from 0 through 100 counting by steps |
| 6057 | -** of 5. | |
| 5628 | +** of 5. In other words, 0, 5, 10, 15, ..., 90, 95, 100. There are a total | |
| 5629 | +** of 21 rows. | |
| 6058 | 5630 | ** |
| 6059 | 5631 | ** SELECT * FROM generate_series(0,100); |
| 6060 | 5632 | ** |
| 6061 | -** Integers from 0 through 100 with a step size of 1. | |
| 5633 | +** Integers from 0 through 100 with a step size of 1. 101 rows. | |
| 6062 | 5634 | ** |
| 6063 | 5635 | ** SELECT * FROM generate_series(20) LIMIT 10; |
| 6064 | 5636 | ** |
| 6065 | -** Integers 20 through 29. | |
| 5637 | +** Integers 20 through 29. 10 rows. | |
| 6066 | 5638 | ** |
| 6067 | 5639 | ** SELECT * FROM generate_series(0,-100,-5); |
| 6068 | 5640 | ** |
| 6069 | -** Integers 0 -5 -10 ... -100. | |
| 5641 | +** Integers 0 -5 -10 ... -100. 21 rows. | |
| 6070 | 5642 | ** |
| 6071 | 5643 | ** SELECT * FROM generate_series(0,-1); |
| 6072 | 5644 | ** |
| 6073 | 5645 | ** Empty sequence. |
| 6074 | 5646 | ** |
| @@ -6140,143 +5712,92 @@ | ||
| 6140 | 5712 | #include <string.h> |
| 6141 | 5713 | #include <limits.h> |
| 6142 | 5714 | #include <math.h> |
| 6143 | 5715 | |
| 6144 | 5716 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 6145 | -/* | |
| 6146 | -** Return that member of a generate_series(...) sequence whose 0-based | |
| 6147 | -** index is ix. The 0th member is given by smBase. The sequence members | |
| 6148 | -** progress per ix increment by smStep. | |
| 6149 | -*/ | |
| 6150 | -static sqlite3_int64 genSeqMember( | |
| 6151 | - sqlite3_int64 smBase, | |
| 6152 | - sqlite3_int64 smStep, | |
| 6153 | - sqlite3_uint64 ix | |
| 6154 | -){ | |
| 6155 | - static const sqlite3_uint64 mxI64 = | |
| 6156 | - ((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff; | |
| 6157 | - if( ix>=mxI64 ){ | |
| 6158 | - /* Get ix into signed i64 range. */ | |
| 6159 | - ix -= mxI64; | |
| 6160 | - /* With 2's complement ALU, this next can be 1 step, but is split into | |
| 6161 | - * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */ | |
| 6162 | - smBase += (mxI64/2) * smStep; | |
| 6163 | - smBase += (mxI64 - mxI64/2) * smStep; | |
| 6164 | - } | |
| 6165 | - /* Under UBSAN (or on 1's complement machines), must do this last term | |
| 6166 | - * in steps to avoid the dreaded (and harmless) signed multiply overflow. */ | |
| 6167 | - if( ix>=2 ){ | |
| 6168 | - sqlite3_int64 ix2 = (sqlite3_int64)ix/2; | |
| 6169 | - smBase += ix2*smStep; | |
| 6170 | - ix -= ix2; | |
| 6171 | - } | |
| 6172 | - return smBase + ((sqlite3_int64)ix)*smStep; | |
| 6173 | -} | |
| 6174 | - | |
| 6175 | -/* typedef unsigned char u8; */ | |
| 6176 | - | |
| 6177 | -typedef struct SequenceSpec { | |
| 6178 | - sqlite3_int64 iOBase; /* Original starting value ("start") */ | |
| 6179 | - sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ | |
| 6180 | - sqlite3_int64 iBase; /* Starting value to actually use */ | |
| 6181 | - sqlite3_int64 iTerm; /* Terminal value to actually use */ | |
| 6182 | - sqlite3_int64 iStep; /* Increment ("step") */ | |
| 6183 | - sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */ | |
| 6184 | - sqlite3_uint64 uSeqIndexNow; /* Current index during generation */ | |
| 6185 | - sqlite3_int64 iValueNow; /* Current value during generation */ | |
| 6186 | - u8 isNotEOF; /* Sequence generation not exhausted */ | |
| 6187 | - u8 isReversing; /* Sequence is being reverse generated */ | |
| 6188 | -} SequenceSpec; | |
| 6189 | - | |
| 6190 | -/* | |
| 6191 | -** Prepare a SequenceSpec for use in generating an integer series | |
| 6192 | -** given initialized iBase, iTerm and iStep values. Sequence is | |
| 6193 | -** initialized per given isReversing. Other members are computed. | |
| 6194 | -*/ | |
| 6195 | -static void setupSequence( SequenceSpec *pss ){ | |
| 6196 | - int bSameSigns; | |
| 6197 | - pss->uSeqIndexMax = 0; | |
| 6198 | - pss->isNotEOF = 0; | |
| 6199 | - bSameSigns = (pss->iBase < 0)==(pss->iTerm < 0); | |
| 6200 | - if( pss->iTerm < pss->iBase ){ | |
| 6201 | - sqlite3_uint64 nuspan = 0; | |
| 6202 | - if( bSameSigns ){ | |
| 6203 | - nuspan = (sqlite3_uint64)(pss->iBase - pss->iTerm); | |
| 6204 | - }else{ | |
| 6205 | - /* Under UBSAN (or on 1's complement machines), must do this in steps. | |
| 6206 | - * In this clause, iBase>=0 and iTerm<0 . */ | |
| 6207 | - nuspan = 1; | |
| 6208 | - nuspan += pss->iBase; | |
| 6209 | - nuspan += -(pss->iTerm+1); | |
| 6210 | - } | |
| 6211 | - if( pss->iStep<0 ){ | |
| 6212 | - pss->isNotEOF = 1; | |
| 6213 | - if( nuspan==ULONG_MAX ){ | |
| 6214 | - pss->uSeqIndexMax = ( pss->iStep>LLONG_MIN )? nuspan/-pss->iStep : 1; | |
| 6215 | - }else if( pss->iStep>LLONG_MIN ){ | |
| 6216 | - pss->uSeqIndexMax = nuspan/-pss->iStep; | |
| 6217 | - } | |
| 6218 | - } | |
| 6219 | - }else if( pss->iTerm > pss->iBase ){ | |
| 6220 | - sqlite3_uint64 puspan = 0; | |
| 6221 | - if( bSameSigns ){ | |
| 6222 | - puspan = (sqlite3_uint64)(pss->iTerm - pss->iBase); | |
| 6223 | - }else{ | |
| 6224 | - /* Under UBSAN (or on 1's complement machines), must do this in steps. | |
| 6225 | - * In this clause, iTerm>=0 and iBase<0 . */ | |
| 6226 | - puspan = 1; | |
| 6227 | - puspan += pss->iTerm; | |
| 6228 | - puspan += -(pss->iBase+1); | |
| 6229 | - } | |
| 6230 | - if( pss->iStep>0 ){ | |
| 6231 | - pss->isNotEOF = 1; | |
| 6232 | - pss->uSeqIndexMax = puspan/pss->iStep; | |
| 6233 | - } | |
| 6234 | - }else if( pss->iTerm == pss->iBase ){ | |
| 6235 | - pss->isNotEOF = 1; | |
| 6236 | - pss->uSeqIndexMax = 0; | |
| 6237 | - } | |
| 6238 | - pss->uSeqIndexNow = (pss->isReversing)? pss->uSeqIndexMax : 0; | |
| 6239 | - pss->iValueNow = (pss->isReversing) | |
| 6240 | - ? genSeqMember(pss->iBase, pss->iStep, pss->uSeqIndexMax) | |
| 6241 | - : pss->iBase; | |
| 6242 | -} | |
| 6243 | - | |
| 6244 | -/* | |
| 6245 | -** Progress sequence generator to yield next value, if any. | |
| 6246 | -** Leave its state to either yield next value or be at EOF. | |
| 6247 | -** Return whether there is a next value, or 0 at EOF. | |
| 6248 | -*/ | |
| 6249 | -static int progressSequence( SequenceSpec *pss ){ | |
| 6250 | - if( !pss->isNotEOF ) return 0; | |
| 6251 | - if( pss->isReversing ){ | |
| 6252 | - if( pss->uSeqIndexNow > 0 ){ | |
| 6253 | - pss->uSeqIndexNow--; | |
| 6254 | - pss->iValueNow -= pss->iStep; | |
| 6255 | - }else{ | |
| 6256 | - pss->isNotEOF = 0; | |
| 6257 | - } | |
| 6258 | - }else{ | |
| 6259 | - if( pss->uSeqIndexNow < pss->uSeqIndexMax ){ | |
| 6260 | - pss->uSeqIndexNow++; | |
| 6261 | - pss->iValueNow += pss->iStep; | |
| 6262 | - }else{ | |
| 6263 | - pss->isNotEOF = 0; | |
| 6264 | - } | |
| 6265 | - } | |
| 6266 | - return pss->isNotEOF; | |
| 6267 | -} | |
| 6268 | 5717 | |
| 6269 | 5718 | /* series_cursor is a subclass of sqlite3_vtab_cursor which will |
| 6270 | 5719 | ** serve as the underlying representation of a cursor that scans |
| 6271 | -** over rows of the result | |
| 5720 | +** over rows of the result. | |
| 5721 | +** | |
| 5722 | +** iOBase, iOTerm, and iOStep are the original values of the | |
| 5723 | +** start=, stop=, and step= constraints on the query. These are | |
| 5724 | +** the values reported by the start, stop, and step columns of the | |
| 5725 | +** virtual table. | |
| 5726 | +** | |
| 5727 | +** iBase, iTerm, iStep, and bDescp are the actual values used to generate | |
| 5728 | +** the sequence. These might be different from the iOxxxx values. | |
| 5729 | +** For example in | |
| 5730 | +** | |
| 5731 | +** SELECT value FROM generate_series(1,11,2) | |
| 5732 | +** WHERE value BETWEEN 4 AND 8; | |
| 5733 | +** | |
| 5734 | +** The iOBase is 1, but the iBase is 5. iOTerm is 11 but iTerm is 7. | |
| 5735 | +** Another example: | |
| 5736 | +** | |
| 5737 | +** SELECT value FROM generate_series(1,15,3) ORDER BY value DESC; | |
| 5738 | +** | |
| 5739 | +** The cursor initialization for the above query is: | |
| 5740 | +** | |
| 5741 | +** iOBase = 1 iBase = 13 | |
| 5742 | +** iOTerm = 15 iTerm = 1 | |
| 5743 | +** iOStep = 3 iStep = 3 bDesc = 1 | |
| 5744 | +** | |
| 5745 | +** The actual step size is unsigned so that can have a value of | |
| 5746 | +** +9223372036854775808 which is needed for querys like this: | |
| 5747 | +** | |
| 5748 | +** SELECT value | |
| 5749 | +** FROM generate_series(9223372036854775807, | |
| 5750 | +** -9223372036854775808, | |
| 5751 | +** -9223372036854775808) | |
| 5752 | +** ORDER BY value ASC; | |
| 5753 | +** | |
| 5754 | +** The setup for the previous query will be: | |
| 5755 | +** | |
| 5756 | +** iOBase = 9223372036854775807 iBase = -1 | |
| 5757 | +** iOTerm = -9223372036854775808 iTerm = 9223372036854775807 | |
| 5758 | +** iOStep = -9223372036854775808 iStep = 9223372036854775808 bDesc = 0 | |
| 6272 | 5759 | */ |
| 5760 | +/* typedef unsigned char u8; */ | |
| 6273 | 5761 | typedef struct series_cursor series_cursor; |
| 6274 | 5762 | struct series_cursor { |
| 6275 | 5763 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 6276 | - SequenceSpec ss; /* (this) Derived class data */ | |
| 5764 | + sqlite3_int64 iOBase; /* Original starting value ("start") */ | |
| 5765 | + sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ | |
| 5766 | + sqlite3_int64 iOStep; /* Original step value */ | |
| 5767 | + sqlite3_int64 iBase; /* Starting value to actually use */ | |
| 5768 | + sqlite3_int64 iTerm; /* Terminal value to actually use */ | |
| 5769 | + sqlite3_uint64 iStep; /* The step size */ | |
| 5770 | + sqlite3_int64 iValue; /* Current value */ | |
| 5771 | + u8 bDesc; /* iStep is really negative */ | |
| 5772 | + u8 bDone; /* True if stepped past last element */ | |
| 6277 | 5773 | }; |
| 5774 | + | |
| 5775 | +/* | |
| 5776 | +** Computed the difference between two 64-bit signed integers using a | |
| 5777 | +** convoluted computation designed to work around the silly restriction | |
| 5778 | +** against signed integer overflow in C. | |
| 5779 | +*/ | |
| 5780 | +static sqlite3_uint64 span64(sqlite3_int64 a, sqlite3_int64 b){ | |
| 5781 | + assert( a>=b ); | |
| 5782 | + return (*(sqlite3_uint64*)&a) - (*(sqlite3_uint64*)&b); | |
| 5783 | +} | |
| 5784 | + | |
| 5785 | +/* | |
| 5786 | +** Add or substract an unsigned 64-bit integer from a signed 64-bit integer | |
| 5787 | +** and return the new signed 64-bit integer. | |
| 5788 | +*/ | |
| 5789 | +static sqlite3_int64 add64(sqlite3_int64 a, sqlite3_uint64 b){ | |
| 5790 | + sqlite3_uint64 x = *(sqlite3_uint64*)&a; | |
| 5791 | + x += b; | |
| 5792 | + return *(sqlite3_int64*)&x; | |
| 5793 | +} | |
| 5794 | +static sqlite3_int64 sub64(sqlite3_int64 a, sqlite3_uint64 b){ | |
| 5795 | + sqlite3_uint64 x = *(sqlite3_uint64*)&a; | |
| 5796 | + x -= b; | |
| 5797 | + return *(sqlite3_int64*)&x; | |
| 5798 | +} | |
| 6278 | 5799 | |
| 6279 | 5800 | /* |
| 6280 | 5801 | ** The seriesConnect() method is invoked to create a new |
| 6281 | 5802 | ** series_vtab that describes the generate_series virtual table. |
| 6282 | 5803 | ** |
| @@ -6354,11 +5875,19 @@ | ||
| 6354 | 5875 | /* |
| 6355 | 5876 | ** Advance a series_cursor to its next row of output. |
| 6356 | 5877 | */ |
| 6357 | 5878 | static int seriesNext(sqlite3_vtab_cursor *cur){ |
| 6358 | 5879 | series_cursor *pCur = (series_cursor*)cur; |
| 6359 | - progressSequence( & pCur->ss ); | |
| 5880 | + if( pCur->iValue==pCur->iTerm ){ | |
| 5881 | + pCur->bDone = 1; | |
| 5882 | + }else if( pCur->bDesc ){ | |
| 5883 | + pCur->iValue = sub64(pCur->iValue, pCur->iStep); | |
| 5884 | + assert( pCur->iValue>=pCur->iTerm ); | |
| 5885 | + }else{ | |
| 5886 | + pCur->iValue = add64(pCur->iValue, pCur->iStep); | |
| 5887 | + assert( pCur->iValue<=pCur->iTerm ); | |
| 5888 | + } | |
| 6360 | 5889 | return SQLITE_OK; |
| 6361 | 5890 | } |
| 6362 | 5891 | |
| 6363 | 5892 | /* |
| 6364 | 5893 | ** Return values of columns for the row at which the series_cursor |
| @@ -6370,41 +5899,41 @@ | ||
| 6370 | 5899 | int i /* Which column to return */ |
| 6371 | 5900 | ){ |
| 6372 | 5901 | series_cursor *pCur = (series_cursor*)cur; |
| 6373 | 5902 | sqlite3_int64 x = 0; |
| 6374 | 5903 | switch( i ){ |
| 6375 | - case SERIES_COLUMN_START: x = pCur->ss.iOBase; break; | |
| 6376 | - case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break; | |
| 6377 | - case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; | |
| 6378 | - default: x = pCur->ss.iValueNow; break; | |
| 5904 | + case SERIES_COLUMN_START: x = pCur->iOBase; break; | |
| 5905 | + case SERIES_COLUMN_STOP: x = pCur->iOTerm; break; | |
| 5906 | + case SERIES_COLUMN_STEP: x = pCur->iOStep; break; | |
| 5907 | + default: x = pCur->iValue; break; | |
| 6379 | 5908 | } |
| 6380 | 5909 | sqlite3_result_int64(ctx, x); |
| 6381 | 5910 | return SQLITE_OK; |
| 6382 | 5911 | } |
| 6383 | 5912 | |
| 6384 | 5913 | #ifndef LARGEST_UINT64 |
| 6385 | -#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) | |
| 6386 | -#define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) | |
| 6387 | -#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) | |
| 5914 | +#define LARGEST_INT64 ((sqlite3_int64)0x7fffffffffffffffLL) | |
| 5915 | +#define LARGEST_UINT64 ((sqlite3_uint64)0xffffffffffffffffULL) | |
| 5916 | +#define SMALLEST_INT64 ((sqlite3_int64)0x8000000000000000LL) | |
| 6388 | 5917 | #endif |
| 6389 | 5918 | |
| 6390 | 5919 | /* |
| 6391 | 5920 | ** The rowid is the same as the value. |
| 6392 | 5921 | */ |
| 6393 | 5922 | static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 6394 | 5923 | series_cursor *pCur = (series_cursor*)cur; |
| 6395 | - *pRowid = pCur->ss.iValueNow; | |
| 5924 | + *pRowid = pCur->iValue; | |
| 6396 | 5925 | return SQLITE_OK; |
| 6397 | 5926 | } |
| 6398 | 5927 | |
| 6399 | 5928 | /* |
| 6400 | 5929 | ** Return TRUE if the cursor has been moved off of the last |
| 6401 | 5930 | ** row of output. |
| 6402 | 5931 | */ |
| 6403 | 5932 | static int seriesEof(sqlite3_vtab_cursor *cur){ |
| 6404 | 5933 | series_cursor *pCur = (series_cursor*)cur; |
| 6405 | - return !pCur->ss.isNotEOF; | |
| 5934 | + return pCur->bDone; | |
| 6406 | 5935 | } |
| 6407 | 5936 | |
| 6408 | 5937 | /* True to cause run-time checking of the start=, stop=, and/or step= |
| 6409 | 5938 | ** parameters. The only reason to do this is for testing the |
| 6410 | 5939 | ** constraint checking logic for virtual tables in the SQLite core. |
| @@ -6411,10 +5940,63 @@ | ||
| 6411 | 5940 | */ |
| 6412 | 5941 | #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY |
| 6413 | 5942 | # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 |
| 6414 | 5943 | #endif |
| 6415 | 5944 | |
| 5945 | +/* | |
| 5946 | +** Return the number of steps between pCur->iBase and pCur->iTerm if | |
| 5947 | +** the step width is pCur->iStep. | |
| 5948 | +*/ | |
| 5949 | +static sqlite3_uint64 seriesSteps(series_cursor *pCur){ | |
| 5950 | + if( pCur->bDesc ){ | |
| 5951 | + assert( pCur->iBase >= pCur->iTerm ); | |
| 5952 | + return span64(pCur->iBase, pCur->iTerm)/pCur->iStep; | |
| 5953 | + }else{ | |
| 5954 | + assert( pCur->iBase <= pCur->iTerm ); | |
| 5955 | + return span64(pCur->iTerm, pCur->iBase)/pCur->iStep; | |
| 5956 | + } | |
| 5957 | +} | |
| 5958 | + | |
| 5959 | +#if defined(SQLITE_ENABLE_MATH_FUNCTIONS) || defined(_WIN32) | |
| 5960 | +/* | |
| 5961 | +** Case 1 (the most common case): | |
| 5962 | +** The standard math library is available so use ceil() and floor() from there. | |
| 5963 | +*/ | |
| 5964 | +static double seriesCeil(double r){ return ceil(r); } | |
| 5965 | +static double seriesFloor(double r){ return floor(r); } | |
| 5966 | +#elif defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) | |
| 5967 | +/* | |
| 5968 | +** Case 2 (2nd most common): Use GCC/Clang builtins | |
| 5969 | +*/ | |
| 5970 | +static double seriesCeil(double r){ return __builtin_ceil(r); } | |
| 5971 | +static double seriesFloor(double r){ return __builtin_floor(r); } | |
| 5972 | +#else | |
| 5973 | +/* | |
| 5974 | +** Case 3 (rarely happens): Use home-grown ceil() and floor() routines. | |
| 5975 | +*/ | |
| 5976 | +static double seriesCeil(double r){ | |
| 5977 | + sqlite3_int64 x; | |
| 5978 | + if( r!=r ) return r; | |
| 5979 | + if( r<=(-4503599627370496.0) ) return r; | |
| 5980 | + if( r>=(+4503599627370496.0) ) return r; | |
| 5981 | + x = (sqlite3_int64)r; | |
| 5982 | + if( r==(double)x ) return r; | |
| 5983 | + if( r>(double)x ) x++; | |
| 5984 | + return (double)x; | |
| 5985 | +} | |
| 5986 | +static double seriesFloor(double r){ | |
| 5987 | + sqlite3_int64 x; | |
| 5988 | + if( r!=r ) return r; | |
| 5989 | + if( r<=(-4503599627370496.0) ) return r; | |
| 5990 | + if( r>=(+4503599627370496.0) ) return r; | |
| 5991 | + x = (sqlite3_int64)r; | |
| 5992 | + if( r==(double)x ) return r; | |
| 5993 | + if( r<(double)x ) x--; | |
| 5994 | + return (double)x; | |
| 5995 | +} | |
| 5996 | +#endif | |
| 5997 | + | |
| 6416 | 5998 | /* |
| 6417 | 5999 | ** This method is called to "rewind" the series_cursor object back |
| 6418 | 6000 | ** to the first row of output. This method is always called at least |
| 6419 | 6001 | ** once prior to any call to seriesColumn() or seriesRowid() or |
| 6420 | 6002 | ** seriesEof(). |
| @@ -6444,185 +6026,243 @@ | ||
| 6444 | 6026 | sqlite3_vtab_cursor *pVtabCursor, |
| 6445 | 6027 | int idxNum, const char *idxStrUnused, |
| 6446 | 6028 | int argc, sqlite3_value **argv |
| 6447 | 6029 | ){ |
| 6448 | 6030 | series_cursor *pCur = (series_cursor *)pVtabCursor; |
| 6449 | - int i = 0; | |
| 6450 | - int returnNoRows = 0; | |
| 6451 | - sqlite3_int64 iMin = SMALLEST_INT64; | |
| 6452 | - sqlite3_int64 iMax = LARGEST_INT64; | |
| 6453 | - sqlite3_int64 iLimit = 0; | |
| 6454 | - sqlite3_int64 iOffset = 0; | |
| 6031 | + int iArg = 0; /* Arguments used so far */ | |
| 6032 | + int i; /* Loop counter */ | |
| 6033 | + sqlite3_int64 iMin = SMALLEST_INT64; /* Smallest allowed output value */ | |
| 6034 | + sqlite3_int64 iMax = LARGEST_INT64; /* Largest allowed output value */ | |
| 6035 | + sqlite3_int64 iLimit = 0; /* if >0, the value of the LIMIT */ | |
| 6036 | + sqlite3_int64 iOffset = 0; /* if >0, the value of the OFFSET */ | |
| 6455 | 6037 | |
| 6456 | 6038 | (void)idxStrUnused; |
| 6039 | + | |
| 6040 | + /* If any constraints have a NULL value, then return no rows. | |
| 6041 | + ** See ticket https://sqlite.org/src/info/fac496b61722daf2 | |
| 6042 | + */ | |
| 6043 | + for(i=0; i<argc; i++){ | |
| 6044 | + if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ | |
| 6045 | + goto series_no_rows; | |
| 6046 | + } | |
| 6047 | + } | |
| 6048 | + | |
| 6049 | + /* Capture the three HIDDEN parameters to the virtual table and insert | |
| 6050 | + ** default values for any parameters that are omitted. | |
| 6051 | + */ | |
| 6457 | 6052 | if( idxNum & 0x01 ){ |
| 6458 | - pCur->ss.iBase = sqlite3_value_int64(argv[i++]); | |
| 6053 | + pCur->iOBase = sqlite3_value_int64(argv[iArg++]); | |
| 6459 | 6054 | }else{ |
| 6460 | - pCur->ss.iBase = 0; | |
| 6055 | + pCur->iOBase = 0; | |
| 6461 | 6056 | } |
| 6462 | 6057 | if( idxNum & 0x02 ){ |
| 6463 | - pCur->ss.iTerm = sqlite3_value_int64(argv[i++]); | |
| 6058 | + pCur->iOTerm = sqlite3_value_int64(argv[iArg++]); | |
| 6464 | 6059 | }else{ |
| 6465 | - pCur->ss.iTerm = 0xffffffff; | |
| 6060 | + pCur->iOTerm = 0xffffffff; | |
| 6466 | 6061 | } |
| 6467 | 6062 | if( idxNum & 0x04 ){ |
| 6468 | - pCur->ss.iStep = sqlite3_value_int64(argv[i++]); | |
| 6469 | - if( pCur->ss.iStep==0 ){ | |
| 6470 | - pCur->ss.iStep = 1; | |
| 6471 | - }else if( pCur->ss.iStep<0 ){ | |
| 6472 | - if( (idxNum & 0x10)==0 ) idxNum |= 0x08; | |
| 6473 | - } | |
| 6063 | + pCur->iOStep = sqlite3_value_int64(argv[iArg++]); | |
| 6064 | + if( pCur->iOStep==0 ) pCur->iOStep = 1; | |
| 6474 | 6065 | }else{ |
| 6475 | - pCur->ss.iStep = 1; | |
| 6066 | + pCur->iOStep = 1; | |
| 6476 | 6067 | } |
| 6477 | 6068 | |
| 6478 | 6069 | /* If there are constraints on the value column but there are |
| 6479 | 6070 | ** no constraints on the start, stop, and step columns, then |
| 6480 | 6071 | ** initialize the default range to be the entire range of 64-bit signed |
| 6481 | 6072 | ** integers. This range will contracted by the value column constraints |
| 6482 | 6073 | ** further below. |
| 6483 | 6074 | */ |
| 6484 | 6075 | if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ |
| 6485 | - pCur->ss.iBase = SMALLEST_INT64; | |
| 6076 | + pCur->iOBase = SMALLEST_INT64; | |
| 6486 | 6077 | } |
| 6487 | 6078 | if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ |
| 6488 | - pCur->ss.iTerm = LARGEST_INT64; | |
| 6079 | + pCur->iOTerm = LARGEST_INT64; | |
| 6489 | 6080 | } |
| 6490 | - pCur->ss.iOBase = pCur->ss.iBase; | |
| 6491 | - pCur->ss.iOTerm = pCur->ss.iTerm; | |
| 6081 | + pCur->iBase = pCur->iOBase; | |
| 6082 | + pCur->iTerm = pCur->iOTerm; | |
| 6083 | + if( pCur->iOStep>0 ){ | |
| 6084 | + pCur->iStep = pCur->iOStep; | |
| 6085 | + }else if( pCur->iOStep>SMALLEST_INT64 ){ | |
| 6086 | + pCur->iStep = -pCur->iOStep; | |
| 6087 | + }else{ | |
| 6088 | + pCur->iStep = LARGEST_INT64; | |
| 6089 | + pCur->iStep++; | |
| 6090 | + } | |
| 6091 | + pCur->bDesc = pCur->iOStep<0; | |
| 6092 | + if( pCur->bDesc==0 && pCur->iBase>pCur->iTerm ){ | |
| 6093 | + goto series_no_rows; | |
| 6094 | + } | |
| 6095 | + if( pCur->bDesc!=0 && pCur->iBase<pCur->iTerm ){ | |
| 6096 | + goto series_no_rows; | |
| 6097 | + } | |
| 6492 | 6098 | |
| 6493 | 6099 | /* Extract the LIMIT and OFFSET values, but do not apply them yet. |
| 6494 | 6100 | ** The range must first be constrained by the limits on value. |
| 6495 | 6101 | */ |
| 6496 | 6102 | if( idxNum & 0x20 ){ |
| 6497 | - iLimit = sqlite3_value_int64(argv[i++]); | |
| 6103 | + iLimit = sqlite3_value_int64(argv[iArg++]); | |
| 6498 | 6104 | if( idxNum & 0x40 ){ |
| 6499 | - iOffset = sqlite3_value_int64(argv[i++]); | |
| 6105 | + iOffset = sqlite3_value_int64(argv[iArg++]); | |
| 6500 | 6106 | } |
| 6501 | 6107 | } |
| 6502 | 6108 | |
| 6109 | + /* Narrow the range of iMin and iMax (the minimum and maximum outputs) | |
| 6110 | + ** based on equality and inequality constraints on the "value" column. | |
| 6111 | + */ | |
| 6503 | 6112 | if( idxNum & 0x3380 ){ |
| 6504 | - /* Extract the maximum range of output values determined by | |
| 6505 | - ** constraints on the "value" column. | |
| 6506 | - */ | |
| 6507 | - if( idxNum & 0x0080 ){ | |
| 6508 | - if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ | |
| 6509 | - double r = sqlite3_value_double(argv[i++]); | |
| 6510 | - if( r==ceil(r) ){ | |
| 6113 | + if( idxNum & 0x0080 ){ /* value=X */ | |
| 6114 | + if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ | |
| 6115 | + double r = sqlite3_value_double(argv[iArg++]); | |
| 6116 | + if( r==seriesCeil(r) | |
| 6117 | + && r>=(double)SMALLEST_INT64 | |
| 6118 | + && r<=(double)LARGEST_INT64 | |
| 6119 | + ){ | |
| 6511 | 6120 | iMin = iMax = (sqlite3_int64)r; |
| 6512 | 6121 | }else{ |
| 6513 | - returnNoRows = 1; | |
| 6514 | - } | |
| 6515 | - }else{ | |
| 6516 | - iMin = iMax = sqlite3_value_int64(argv[i++]); | |
| 6517 | - } | |
| 6518 | - }else{ | |
| 6519 | - if( idxNum & 0x0300 ){ | |
| 6520 | - if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ | |
| 6521 | - double r = sqlite3_value_double(argv[i++]); | |
| 6522 | - if( idxNum & 0x0200 && r==ceil(r) ){ | |
| 6523 | - iMin = (sqlite3_int64)ceil(r+1.0); | |
| 6524 | - }else{ | |
| 6525 | - iMin = (sqlite3_int64)ceil(r); | |
| 6526 | - } | |
| 6527 | - }else{ | |
| 6528 | - iMin = sqlite3_value_int64(argv[i++]); | |
| 6529 | - if( idxNum & 0x0200 ){ | |
| 6122 | + goto series_no_rows; | |
| 6123 | + } | |
| 6124 | + }else{ | |
| 6125 | + iMin = iMax = sqlite3_value_int64(argv[iArg++]); | |
| 6126 | + } | |
| 6127 | + }else{ | |
| 6128 | + if( idxNum & 0x0300 ){ /* value>X or value>=X */ | |
| 6129 | + if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ | |
| 6130 | + double r = sqlite3_value_double(argv[iArg++]); | |
| 6131 | + if( r<(double)SMALLEST_INT64 ){ | |
| 6132 | + iMin = SMALLEST_INT64; | |
| 6133 | + }else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){ | |
| 6134 | + iMin = (sqlite3_int64)seriesCeil(r+1.0); | |
| 6135 | + }else{ | |
| 6136 | + iMin = (sqlite3_int64)seriesCeil(r); | |
| 6137 | + } | |
| 6138 | + }else{ | |
| 6139 | + iMin = sqlite3_value_int64(argv[iArg++]); | |
| 6140 | + if( (idxNum & 0x0200)!=0 ){ | |
| 6530 | 6141 | if( iMin==LARGEST_INT64 ){ |
| 6531 | - returnNoRows = 1; | |
| 6142 | + goto series_no_rows; | |
| 6532 | 6143 | }else{ |
| 6533 | 6144 | iMin++; |
| 6534 | 6145 | } |
| 6535 | 6146 | } |
| 6536 | 6147 | } |
| 6537 | 6148 | } |
| 6538 | - if( idxNum & 0x3000 ){ | |
| 6539 | - if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ | |
| 6540 | - double r = sqlite3_value_double(argv[i++]); | |
| 6541 | - if( (idxNum & 0x2000)!=0 && r==floor(r) ){ | |
| 6149 | + if( idxNum & 0x3000 ){ /* value<X or value<=X */ | |
| 6150 | + if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ | |
| 6151 | + double r = sqlite3_value_double(argv[iArg++]); | |
| 6152 | + if( r>(double)LARGEST_INT64 ){ | |
| 6153 | + iMax = LARGEST_INT64; | |
| 6154 | + }else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){ | |
| 6542 | 6155 | iMax = (sqlite3_int64)(r-1.0); |
| 6543 | 6156 | }else{ |
| 6544 | - iMax = (sqlite3_int64)floor(r); | |
| 6157 | + iMax = (sqlite3_int64)seriesFloor(r); | |
| 6545 | 6158 | } |
| 6546 | 6159 | }else{ |
| 6547 | - iMax = sqlite3_value_int64(argv[i++]); | |
| 6160 | + iMax = sqlite3_value_int64(argv[iArg++]); | |
| 6548 | 6161 | if( idxNum & 0x2000 ){ |
| 6549 | 6162 | if( iMax==SMALLEST_INT64 ){ |
| 6550 | - returnNoRows = 1; | |
| 6163 | + goto series_no_rows; | |
| 6551 | 6164 | }else{ |
| 6552 | 6165 | iMax--; |
| 6553 | 6166 | } |
| 6554 | 6167 | } |
| 6555 | 6168 | } |
| 6556 | 6169 | } |
| 6557 | 6170 | if( iMin>iMax ){ |
| 6558 | - returnNoRows = 1; | |
| 6171 | + goto series_no_rows; | |
| 6559 | 6172 | } |
| 6560 | 6173 | } |
| 6561 | 6174 | |
| 6562 | 6175 | /* Try to reduce the range of values to be generated based on |
| 6563 | 6176 | ** constraints on the "value" column. |
| 6564 | 6177 | */ |
| 6565 | - if( pCur->ss.iStep>0 ){ | |
| 6566 | - sqlite3_int64 szStep = pCur->ss.iStep; | |
| 6567 | - if( pCur->ss.iBase<iMin ){ | |
| 6568 | - sqlite3_uint64 d = iMin - pCur->ss.iBase; | |
| 6569 | - pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; | |
| 6570 | - } | |
| 6571 | - if( pCur->ss.iTerm>iMax ){ | |
| 6572 | - pCur->ss.iTerm = iMax; | |
| 6178 | + if( pCur->bDesc==0 ){ | |
| 6179 | + if( pCur->iBase<iMin ){ | |
| 6180 | + sqlite3_uint64 span = span64(iMin,pCur->iBase); | |
| 6181 | + pCur->iBase = add64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); | |
| 6182 | + if( pCur->iBase<iMin ){ | |
| 6183 | + if( pCur->iBase > sub64(LARGEST_INT64, pCur->iStep) ){ | |
| 6184 | + goto series_no_rows; | |
| 6185 | + } | |
| 6186 | + pCur->iBase = add64(pCur->iBase, pCur->iStep); | |
| 6187 | + } | |
| 6188 | + } | |
| 6189 | + if( pCur->iTerm>iMax ){ | |
| 6190 | + pCur->iTerm = iMax; | |
| 6573 | 6191 | } |
| 6574 | 6192 | }else{ |
| 6575 | - sqlite3_int64 szStep = -pCur->ss.iStep; | |
| 6576 | - assert( szStep>0 ); | |
| 6577 | - if( pCur->ss.iBase>iMax ){ | |
| 6578 | - sqlite3_uint64 d = pCur->ss.iBase - iMax; | |
| 6579 | - pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; | |
| 6580 | - } | |
| 6581 | - if( pCur->ss.iTerm<iMin ){ | |
| 6582 | - pCur->ss.iTerm = iMin; | |
| 6193 | + if( pCur->iBase>iMax ){ | |
| 6194 | + sqlite3_uint64 span = span64(pCur->iBase,iMax); | |
| 6195 | + pCur->iBase = sub64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); | |
| 6196 | + if( pCur->iBase>iMax ){ | |
| 6197 | + if( pCur->iBase < add64(SMALLEST_INT64, pCur->iStep) ){ | |
| 6198 | + goto series_no_rows; | |
| 6199 | + } | |
| 6200 | + pCur->iBase = sub64(pCur->iBase, pCur->iStep); | |
| 6201 | + } | |
| 6202 | + } | |
| 6203 | + if( pCur->iTerm<iMin ){ | |
| 6204 | + pCur->iTerm = iMin; | |
| 6583 | 6205 | } |
| 6584 | 6206 | } |
| 6585 | 6207 | } |
| 6208 | + | |
| 6209 | + /* Adjust iTerm so that it is exactly the last value of the series. | |
| 6210 | + */ | |
| 6211 | + if( pCur->bDesc==0 ){ | |
| 6212 | + if( pCur->iBase>pCur->iTerm ){ | |
| 6213 | + goto series_no_rows; | |
| 6214 | + } | |
| 6215 | + pCur->iTerm = sub64(pCur->iTerm, | |
| 6216 | + span64(pCur->iTerm,pCur->iBase) % pCur->iStep); | |
| 6217 | + }else{ | |
| 6218 | + if( pCur->iBase<pCur->iTerm ){ | |
| 6219 | + goto series_no_rows; | |
| 6220 | + } | |
| 6221 | + pCur->iTerm = add64(pCur->iTerm, | |
| 6222 | + span64(pCur->iBase,pCur->iTerm) % pCur->iStep); | |
| 6223 | + } | |
| 6224 | + | |
| 6225 | + /* Transform the series generator to output values in the requested | |
| 6226 | + ** order. | |
| 6227 | + */ | |
| 6228 | + if( ((idxNum & 0x0008)!=0 && pCur->bDesc==0) | |
| 6229 | + || ((idxNum & 0x0010)!=0 && pCur->bDesc!=0) | |
| 6230 | + ){ | |
| 6231 | + sqlite3_int64 tmp = pCur->iBase; | |
| 6232 | + pCur->iBase = pCur->iTerm; | |
| 6233 | + pCur->iTerm = tmp; | |
| 6234 | + pCur->bDesc = !pCur->bDesc; | |
| 6235 | + } | |
| 6586 | 6236 | |
| 6587 | 6237 | /* Apply LIMIT and OFFSET constraints, if any */ |
| 6238 | + assert( pCur->iStep!=0 ); | |
| 6588 | 6239 | if( idxNum & 0x20 ){ |
| 6589 | 6240 | if( iOffset>0 ){ |
| 6590 | - pCur->ss.iBase += pCur->ss.iStep*iOffset; | |
| 6591 | - } | |
| 6592 | - if( iLimit>=0 ){ | |
| 6593 | - sqlite3_int64 iTerm; | |
| 6594 | - iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; | |
| 6595 | - if( pCur->ss.iStep<0 ){ | |
| 6596 | - if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; | |
| 6597 | - }else{ | |
| 6598 | - if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; | |
| 6599 | - } | |
| 6600 | - } | |
| 6601 | - } | |
| 6602 | - | |
| 6603 | - | |
| 6604 | - for(i=0; i<argc; i++){ | |
| 6605 | - if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ | |
| 6606 | - /* If any of the constraints have a NULL value, then return no rows. | |
| 6607 | - ** See ticket https://sqlite.org/src/info/fac496b61722daf2 */ | |
| 6608 | - returnNoRows = 1; | |
| 6609 | - break; | |
| 6610 | - } | |
| 6611 | - } | |
| 6612 | - if( returnNoRows ){ | |
| 6613 | - pCur->ss.iBase = 1; | |
| 6614 | - pCur->ss.iTerm = 0; | |
| 6615 | - pCur->ss.iStep = 1; | |
| 6616 | - } | |
| 6617 | - if( idxNum & 0x08 ){ | |
| 6618 | - pCur->ss.isReversing = pCur->ss.iStep > 0; | |
| 6619 | - }else{ | |
| 6620 | - pCur->ss.isReversing = pCur->ss.iStep < 0; | |
| 6621 | - } | |
| 6622 | - setupSequence( &pCur->ss ); | |
| 6241 | + if( seriesSteps(pCur) < (sqlite3_uint64)iOffset ){ | |
| 6242 | + goto series_no_rows; | |
| 6243 | + }else if( pCur->bDesc ){ | |
| 6244 | + pCur->iBase = sub64(pCur->iBase, pCur->iStep*iOffset); | |
| 6245 | + }else{ | |
| 6246 | + pCur->iBase = add64(pCur->iBase, pCur->iStep*iOffset); | |
| 6247 | + } | |
| 6248 | + } | |
| 6249 | + if( iLimit>=0 && seriesSteps(pCur) > (sqlite3_uint64)iLimit ){ | |
| 6250 | + pCur->iTerm = add64(pCur->iBase, (iLimit - 1)*pCur->iStep); | |
| 6251 | + } | |
| 6252 | + } | |
| 6253 | + pCur->iValue = pCur->iBase; | |
| 6254 | + pCur->bDone = 0; | |
| 6623 | 6255 | return SQLITE_OK; |
| 6256 | + | |
| 6257 | +series_no_rows: | |
| 6258 | + pCur->iBase = 0; | |
| 6259 | + pCur->iTerm = 0; | |
| 6260 | + pCur->iStep = 1; | |
| 6261 | + pCur->bDesc = 0; | |
| 6262 | + pCur->bDone = 1; | |
| 6263 | + return SQLITE_OK; | |
| 6624 | 6264 | } |
| 6625 | 6265 | |
| 6626 | 6266 | /* |
| 6627 | 6267 | ** SQLite will invoke this method one or more times while planning a query |
| 6628 | 6268 | ** that uses the generate_series virtual table. This routine needs to create |
| @@ -6948,10 +6588,12 @@ | ||
| 6948 | 6588 | ** expression and M is the size of the input string. The matcher never |
| 6949 | 6589 | ** exhibits exponential behavior. Note that the X{p,q} operator expands |
| 6950 | 6590 | ** to p copies of X following by q-p copies of X? and that the size of the |
| 6951 | 6591 | ** regular expression in the O(N*M) performance bound is computed after |
| 6952 | 6592 | ** this expansion. |
| 6593 | +** | |
| 6594 | +** To help prevent DoS attacks, the maximum size of the NFA is restricted. | |
| 6953 | 6595 | */ |
| 6954 | 6596 | #include <string.h> |
| 6955 | 6597 | #include <stdlib.h> |
| 6956 | 6598 | /* #include "sqlite3ext.h" */ |
| 6957 | 6599 | SQLITE_EXTENSION_INIT1 |
| @@ -6988,36 +6630,10 @@ | ||
| 6988 | 6630 | #define RE_OP_NOTDIGIT 14 /* Not a digit */ |
| 6989 | 6631 | #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ |
| 6990 | 6632 | #define RE_OP_NOTSPACE 16 /* Not a digit */ |
| 6991 | 6633 | #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ |
| 6992 | 6634 | #define RE_OP_ATSTART 18 /* Currently at the start of the string */ |
| 6993 | - | |
| 6994 | -#if defined(SQLITE_DEBUG) | |
| 6995 | -/* Opcode names used for symbolic debugging */ | |
| 6996 | -static const char *ReOpName[] = { | |
| 6997 | - "EOF", | |
| 6998 | - "MATCH", | |
| 6999 | - "ANY", | |
| 7000 | - "ANYSTAR", | |
| 7001 | - "FORK", | |
| 7002 | - "GOTO", | |
| 7003 | - "ACCEPT", | |
| 7004 | - "CC_INC", | |
| 7005 | - "CC_EXC", | |
| 7006 | - "CC_VALUE", | |
| 7007 | - "CC_RANGE", | |
| 7008 | - "WORD", | |
| 7009 | - "NOTWORD", | |
| 7010 | - "DIGIT", | |
| 7011 | - "NOTDIGIT", | |
| 7012 | - "SPACE", | |
| 7013 | - "NOTSPACE", | |
| 7014 | - "BOUNDARY", | |
| 7015 | - "ATSTART", | |
| 7016 | -}; | |
| 7017 | -#endif /* SQLITE_DEBUG */ | |
| 7018 | - | |
| 7019 | 6635 | |
| 7020 | 6636 | /* Each opcode is a "state" in the NFA */ |
| 7021 | 6637 | typedef unsigned short ReStateNumber; |
| 7022 | 6638 | |
| 7023 | 6639 | /* Because this is an NFA and not a DFA, multiple states can be active at |
| @@ -7051,10 +6667,11 @@ | ||
| 7051 | 6667 | unsigned (*xNextChar)(ReInput*); /* Next character function */ |
| 7052 | 6668 | unsigned char zInit[12]; /* Initial text to match */ |
| 7053 | 6669 | int nInit; /* Number of bytes in zInit */ |
| 7054 | 6670 | unsigned nState; /* Number of entries in aOp[] and aArg[] */ |
| 7055 | 6671 | unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */ |
| 6672 | + unsigned mxAlloc; /* Complexity limit */ | |
| 7056 | 6673 | }; |
| 7057 | 6674 | |
| 7058 | 6675 | /* Add a state to the given state set if it is not already there */ |
| 7059 | 6676 | static void re_add_state(ReStateSet *pSet, int newState){ |
| 7060 | 6677 | unsigned i; |
| @@ -7265,18 +6882,19 @@ | ||
| 7265 | 6882 | return rc; |
| 7266 | 6883 | } |
| 7267 | 6884 | |
| 7268 | 6885 | /* Resize the opcode and argument arrays for an RE under construction. |
| 7269 | 6886 | */ |
| 7270 | -static int re_resize(ReCompiled *p, int N){ | |
| 6887 | +static int re_resize(ReCompiled *p, unsigned int N){ | |
| 7271 | 6888 | char *aOp; |
| 7272 | 6889 | int *aArg; |
| 6890 | + if( N>p->mxAlloc ){ p->zErr = "REGEXP pattern too big"; return 1; } | |
| 7273 | 6891 | aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0])); |
| 7274 | - if( aOp==0 ) return 1; | |
| 6892 | + if( aOp==0 ){ p->zErr = "out of memory"; return 1; } | |
| 7275 | 6893 | p->aOp = aOp; |
| 7276 | 6894 | aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0])); |
| 7277 | - if( aArg==0 ) return 1; | |
| 6895 | + if( aArg==0 ){ p->zErr = "out of memory"; return 1; } | |
| 7278 | 6896 | p->aArg = aArg; |
| 7279 | 6897 | p->nAlloc = N; |
| 7280 | 6898 | return 0; |
| 7281 | 6899 | } |
| 7282 | 6900 | |
| @@ -7303,11 +6921,11 @@ | ||
| 7303 | 6921 | } |
| 7304 | 6922 | |
| 7305 | 6923 | /* Make a copy of N opcodes starting at iStart onto the end of the RE |
| 7306 | 6924 | ** under construction. |
| 7307 | 6925 | */ |
| 7308 | -static void re_copy(ReCompiled *p, int iStart, int N){ | |
| 6926 | +static void re_copy(ReCompiled *p, int iStart, unsigned int N){ | |
| 7309 | 6927 | if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return; |
| 7310 | 6928 | memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0])); |
| 7311 | 6929 | memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0])); |
| 7312 | 6930 | p->nState += N; |
| 7313 | 6931 | } |
| @@ -7456,22 +7074,30 @@ | ||
| 7456 | 7074 | case '^': { |
| 7457 | 7075 | re_append(p, RE_OP_ATSTART, 0); |
| 7458 | 7076 | break; |
| 7459 | 7077 | } |
| 7460 | 7078 | case '{': { |
| 7461 | - int m = 0, n = 0; | |
| 7462 | - int sz, j; | |
| 7079 | + unsigned int m = 0, n = 0; | |
| 7080 | + unsigned int sz, j; | |
| 7463 | 7081 | if( iPrev<0 ) return "'{m,n}' without operand"; |
| 7464 | - while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; } | |
| 7082 | + while( (c=rePeek(p))>='0' && c<='9' ){ | |
| 7083 | + m = m*10 + c - '0'; | |
| 7084 | + if( m*2>p->mxAlloc ) return "REGEXP pattern too big"; | |
| 7085 | + p->sIn.i++; | |
| 7086 | + } | |
| 7465 | 7087 | n = m; |
| 7466 | 7088 | if( c==',' ){ |
| 7467 | 7089 | p->sIn.i++; |
| 7468 | 7090 | n = 0; |
| 7469 | - while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; } | |
| 7091 | + while( (c=rePeek(p))>='0' && c<='9' ){ | |
| 7092 | + n = n*10 + c-'0'; | |
| 7093 | + if( n*2>p->mxAlloc ) return "REGEXP pattern too big"; | |
| 7094 | + p->sIn.i++; | |
| 7095 | + } | |
| 7470 | 7096 | } |
| 7471 | 7097 | if( c!='}' ) return "unmatched '{'"; |
| 7472 | - if( n>0 && n<m ) return "n less than m in '{m,n}'"; | |
| 7098 | + if( n<m ) return "n less than m in '{m,n}'"; | |
| 7473 | 7099 | p->sIn.i++; |
| 7474 | 7100 | sz = p->nState - iPrev; |
| 7475 | 7101 | if( m==0 ){ |
| 7476 | 7102 | if( n==0 ) return "both m and n are zero in '{m,n}'"; |
| 7477 | 7103 | re_insert(p, iPrev, RE_OP_FORK, sz+1); |
| @@ -7483,11 +7109,11 @@ | ||
| 7483 | 7109 | for(j=m; j<n; j++){ |
| 7484 | 7110 | re_append(p, RE_OP_FORK, sz+1); |
| 7485 | 7111 | re_copy(p, iPrev, sz); |
| 7486 | 7112 | } |
| 7487 | 7113 | if( n==0 && m>0 ){ |
| 7488 | - re_append(p, RE_OP_FORK, -sz); | |
| 7114 | + re_append(p, RE_OP_FORK, -(int)sz); | |
| 7489 | 7115 | } |
| 7490 | 7116 | break; |
| 7491 | 7117 | } |
| 7492 | 7118 | case '[': { |
| 7493 | 7119 | unsigned int iFirst = p->nState; |
| @@ -7549,12 +7175,11 @@ | ||
| 7549 | 7175 | |
| 7550 | 7176 | /* Free and reclaim all the memory used by a previously compiled |
| 7551 | 7177 | ** regular expression. Applications should invoke this routine once |
| 7552 | 7178 | ** for every call to re_compile() to avoid memory leaks. |
| 7553 | 7179 | */ |
| 7554 | -static void re_free(void *p){ | |
| 7555 | - ReCompiled *pRe = (ReCompiled*)p; | |
| 7180 | +static void re_free(ReCompiled *pRe){ | |
| 7556 | 7181 | if( pRe ){ |
| 7557 | 7182 | sqlite3_free(pRe->aOp); |
| 7558 | 7183 | sqlite3_free(pRe->aArg); |
| 7559 | 7184 | sqlite3_free(pRe); |
| 7560 | 7185 | } |
| @@ -7564,11 +7189,16 @@ | ||
| 7564 | 7189 | ** Compile a textual regular expression in zIn[] into a compiled regular |
| 7565 | 7190 | ** expression suitable for us by re_match() and return a pointer to the |
| 7566 | 7191 | ** compiled regular expression in *ppRe. Return NULL on success or an |
| 7567 | 7192 | ** error message if something goes wrong. |
| 7568 | 7193 | */ |
| 7569 | -static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ | |
| 7194 | +static const char *re_compile( | |
| 7195 | + ReCompiled **ppRe, /* OUT: write compiled NFA here */ | |
| 7196 | + const char *zIn, /* Input regular expression */ | |
| 7197 | + int mxRe, /* Complexity limit */ | |
| 7198 | + int noCase /* True for caseless comparisons */ | |
| 7199 | +){ | |
| 7570 | 7200 | ReCompiled *pRe; |
| 7571 | 7201 | const char *zErr; |
| 7572 | 7202 | int i, j; |
| 7573 | 7203 | |
| 7574 | 7204 | *ppRe = 0; |
| @@ -7576,13 +7206,15 @@ | ||
| 7576 | 7206 | if( pRe==0 ){ |
| 7577 | 7207 | return "out of memory"; |
| 7578 | 7208 | } |
| 7579 | 7209 | memset(pRe, 0, sizeof(*pRe)); |
| 7580 | 7210 | pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char; |
| 7211 | + pRe->mxAlloc = mxRe; | |
| 7581 | 7212 | if( re_resize(pRe, 30) ){ |
| 7213 | + zErr = pRe->zErr; | |
| 7582 | 7214 | re_free(pRe); |
| 7583 | - return "out of memory"; | |
| 7215 | + return zErr; | |
| 7584 | 7216 | } |
| 7585 | 7217 | if( zIn[0]=='^' ){ |
| 7586 | 7218 | zIn++; |
| 7587 | 7219 | }else{ |
| 7588 | 7220 | re_append(pRe, RE_OP_ANYSTAR, 0); |
| @@ -7630,10 +7262,18 @@ | ||
| 7630 | 7262 | if( j>0 && pRe->zInit[j-1]==0 ) j--; |
| 7631 | 7263 | pRe->nInit = j; |
| 7632 | 7264 | } |
| 7633 | 7265 | return pRe->zErr; |
| 7634 | 7266 | } |
| 7267 | + | |
| 7268 | +/* | |
| 7269 | +** Compute a reasonable limit on the length of the REGEXP NFA. | |
| 7270 | +*/ | |
| 7271 | +static int re_maxlen(sqlite3_context *context){ | |
| 7272 | + sqlite3 *db = sqlite3_context_db_handle(context); | |
| 7273 | + return 75 + sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH,-1)/2; | |
| 7274 | +} | |
| 7635 | 7275 | |
| 7636 | 7276 | /* |
| 7637 | 7277 | ** Implementation of the regexp() SQL function. This function implements |
| 7638 | 7278 | ** the build-in REGEXP operator. The first argument to the function is the |
| 7639 | 7279 | ** pattern and the second argument is the string. So, the SQL statements: |
| @@ -7656,11 +7296,12 @@ | ||
| 7656 | 7296 | (void)argc; /* Unused */ |
| 7657 | 7297 | pRe = sqlite3_get_auxdata(context, 0); |
| 7658 | 7298 | if( pRe==0 ){ |
| 7659 | 7299 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 7660 | 7300 | if( zPattern==0 ) return; |
| 7661 | - zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); | |
| 7301 | + zErr = re_compile(&pRe, zPattern, re_maxlen(context), | |
| 7302 | + sqlite3_user_data(context)!=0); | |
| 7662 | 7303 | if( zErr ){ |
| 7663 | 7304 | re_free(pRe); |
| 7664 | 7305 | sqlite3_result_error(context, zErr, -1); |
| 7665 | 7306 | return; |
| 7666 | 7307 | } |
| @@ -7698,14 +7339,36 @@ | ||
| 7698 | 7339 | sqlite3_str *pStr; |
| 7699 | 7340 | int i; |
| 7700 | 7341 | int n; |
| 7701 | 7342 | char *z; |
| 7702 | 7343 | (void)argc; |
| 7344 | + static const char *ReOpName[] = { | |
| 7345 | + "EOF", | |
| 7346 | + "MATCH", | |
| 7347 | + "ANY", | |
| 7348 | + "ANYSTAR", | |
| 7349 | + "FORK", | |
| 7350 | + "GOTO", | |
| 7351 | + "ACCEPT", | |
| 7352 | + "CC_INC", | |
| 7353 | + "CC_EXC", | |
| 7354 | + "CC_VALUE", | |
| 7355 | + "CC_RANGE", | |
| 7356 | + "WORD", | |
| 7357 | + "NOTWORD", | |
| 7358 | + "DIGIT", | |
| 7359 | + "NOTDIGIT", | |
| 7360 | + "SPACE", | |
| 7361 | + "NOTSPACE", | |
| 7362 | + "BOUNDARY", | |
| 7363 | + "ATSTART", | |
| 7364 | + }; | |
| 7703 | 7365 | |
| 7704 | 7366 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 7705 | 7367 | if( zPattern==0 ) return; |
| 7706 | - zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); | |
| 7368 | + zErr = re_compile(&pRe, zPattern, re_maxlen(context), | |
| 7369 | + sqlite3_user_data(context)!=0); | |
| 7707 | 7370 | if( zErr ){ |
| 7708 | 7371 | re_free(pRe); |
| 7709 | 7372 | sqlite3_result_error(context, zErr, -1); |
| 7710 | 7373 | return; |
| 7711 | 7374 | } |
| @@ -9284,18 +8947,20 @@ | ||
| 9284 | 8947 | if( idxNum & 1 ){ |
| 9285 | 8948 | pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); |
| 9286 | 8949 | if( pCur->nPrefix>0 ){ |
| 9287 | 8950 | pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 9288 | 8951 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 8952 | + pCur->nPrefix = (int)strlen(pCur->zPrefix); | |
| 9289 | 8953 | } |
| 9290 | 8954 | iArg = 1; |
| 9291 | 8955 | } |
| 9292 | 8956 | if( idxNum & 2 ){ |
| 9293 | 8957 | pCur->nLine = sqlite3_value_bytes(argv[iArg]); |
| 9294 | 8958 | if( pCur->nLine>0 ){ |
| 9295 | 8959 | pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 9296 | 8960 | if( pCur->zLine==0 ) return SQLITE_NOMEM; |
| 8961 | + pCur->nLine = (int)strlen(pCur->zLine); | |
| 9297 | 8962 | } |
| 9298 | 8963 | } |
| 9299 | 8964 | if( pCur->zLine!=0 && pCur->zPrefix==0 ){ |
| 9300 | 8965 | int i = pCur->nLine; |
| 9301 | 8966 | while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ |
| @@ -9303,10 +8968,11 @@ | ||
| 9303 | 8968 | } |
| 9304 | 8969 | pCur->nPrefix = pCur->nLine - i; |
| 9305 | 8970 | if( pCur->nPrefix>0 ){ |
| 9306 | 8971 | pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); |
| 9307 | 8972 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 8973 | + pCur->nPrefix = (int)strlen(pCur->zPrefix); | |
| 9308 | 8974 | } |
| 9309 | 8975 | } |
| 9310 | 8976 | pCur->iRowid = 0; |
| 9311 | 8977 | pCur->ePhase = COMPLETION_FIRST_PHASE; |
| 9312 | 8978 | return completionNext(pVtabCursor); |
| @@ -10216,11 +9882,17 @@ | ||
| 10216 | 9882 | "method," /* 6: Compression method (integer) */ |
| 10217 | 9883 | "z HIDDEN" /* 7: Name of zip file */ |
| 10218 | 9884 | ") WITHOUT ROWID;"; |
| 10219 | 9885 | |
| 10220 | 9886 | #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ |
| 10221 | -#define ZIPFILE_BUFFER_SIZE (64*1024) | |
| 9887 | +#define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */ | |
| 9888 | + | |
| 9889 | +/* | |
| 9890 | +** The buffer should be large enough to contain 3 65536 byte strings - the | |
| 9891 | +** filename, the extra field and the file comment. | |
| 9892 | +*/ | |
| 9893 | +#define ZIPFILE_BUFFER_SIZE (200*1024) | |
| 10222 | 9894 | |
| 10223 | 9895 | |
| 10224 | 9896 | /* |
| 10225 | 9897 | ** Magic numbers used to read and write zip files. |
| 10226 | 9898 | ** |
| @@ -10773,10 +10445,11 @@ | ||
| 10773 | 10445 | pLFH->crc32 = zipfileRead32(aRead); |
| 10774 | 10446 | pLFH->szCompressed = zipfileRead32(aRead); |
| 10775 | 10447 | pLFH->szUncompressed = zipfileRead32(aRead); |
| 10776 | 10448 | pLFH->nFile = zipfileRead16(aRead); |
| 10777 | 10449 | pLFH->nExtra = zipfileRead16(aRead); |
| 10450 | + if( pLFH->nFile>ZIPFILE_MX_NAME ) rc = SQLITE_ERROR; | |
| 10778 | 10451 | } |
| 10779 | 10452 | return rc; |
| 10780 | 10453 | } |
| 10781 | 10454 | |
| 10782 | 10455 | |
| @@ -10898,10 +10571,19 @@ | ||
| 10898 | 10571 | || mUnixTime==zipfileMtime(pCds) |
| 10899 | 10572 | || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) |
| 10900 | 10573 | /* || (mUnixTime % 2) */ |
| 10901 | 10574 | ); |
| 10902 | 10575 | } |
| 10576 | + | |
| 10577 | +/* | |
| 10578 | +** Set (*pzErr) to point to a buffer from sqlite3_malloc() containing a | |
| 10579 | +** generic corruption message and return SQLITE_CORRUPT; | |
| 10580 | +*/ | |
| 10581 | +static int zipfileCorrupt(char **pzErr){ | |
| 10582 | + *pzErr = sqlite3_mprintf("zip archive is corrupt"); | |
| 10583 | + return SQLITE_CORRUPT; | |
| 10584 | +} | |
| 10903 | 10585 | |
| 10904 | 10586 | /* |
| 10905 | 10587 | ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in |
| 10906 | 10588 | ** size) containing an entire zip archive image. Or, if aBlob is NULL, |
| 10907 | 10589 | ** then pFile is a file-handle open on a zip file. In either case, this |
| @@ -10921,16 +10603,19 @@ | ||
| 10921 | 10603 | ZipfileEntry **ppEntry /* OUT: Pointer to new object */ |
| 10922 | 10604 | ){ |
| 10923 | 10605 | u8 *aRead; |
| 10924 | 10606 | char **pzErr = &pTab->base.zErrMsg; |
| 10925 | 10607 | int rc = SQLITE_OK; |
| 10926 | - (void)nBlob; | |
| 10927 | 10608 | |
| 10928 | 10609 | if( aBlob==0 ){ |
| 10929 | 10610 | aRead = pTab->aBuffer; |
| 10930 | 10611 | rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); |
| 10931 | 10612 | }else{ |
| 10613 | + if( (iOff+ZIPFILE_CDS_FIXED_SZ)>nBlob ){ | |
| 10614 | + /* Not enough data for the CDS structure. Corruption. */ | |
| 10615 | + return zipfileCorrupt(pzErr); | |
| 10616 | + } | |
| 10932 | 10617 | aRead = (u8*)&aBlob[iOff]; |
| 10933 | 10618 | } |
| 10934 | 10619 | |
| 10935 | 10620 | if( rc==SQLITE_OK ){ |
| 10936 | 10621 | sqlite3_int64 nAlloc; |
| @@ -10957,10 +10642,13 @@ | ||
| 10957 | 10642 | rc = zipfileReadData( |
| 10958 | 10643 | pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr |
| 10959 | 10644 | ); |
| 10960 | 10645 | }else{ |
| 10961 | 10646 | aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; |
| 10647 | + if( (iOff + ZIPFILE_LFH_FIXED_SZ + nFile + nExtra)>nBlob ){ | |
| 10648 | + rc = zipfileCorrupt(pzErr); | |
| 10649 | + } | |
| 10962 | 10650 | } |
| 10963 | 10651 | } |
| 10964 | 10652 | |
| 10965 | 10653 | if( rc==SQLITE_OK ){ |
| 10966 | 10654 | u32 *pt = &pNew->mUnixTime; |
| @@ -10979,19 +10667,26 @@ | ||
| 10979 | 10667 | ZipfileLFH lfh; |
| 10980 | 10668 | if( pFile ){ |
| 10981 | 10669 | rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); |
| 10982 | 10670 | }else{ |
| 10983 | 10671 | aRead = (u8*)&aBlob[pNew->cds.iOffset]; |
| 10672 | + if( (pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ)>nBlob ){ | |
| 10673 | + rc = zipfileCorrupt(pzErr); | |
| 10674 | + } | |
| 10984 | 10675 | } |
| 10985 | 10676 | |
| 10986 | 10677 | if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh); |
| 10987 | 10678 | if( rc==SQLITE_OK ){ |
| 10988 | 10679 | pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; |
| 10989 | 10680 | pNew->iDataOff += lfh.nFile + lfh.nExtra; |
| 10990 | 10681 | if( aBlob && pNew->cds.szCompressed ){ |
| 10991 | - pNew->aData = &pNew->aExtra[nExtra]; | |
| 10992 | - memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); | |
| 10682 | + if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){ | |
| 10683 | + rc = zipfileCorrupt(pzErr); | |
| 10684 | + }else{ | |
| 10685 | + pNew->aData = &pNew->aExtra[nExtra]; | |
| 10686 | + memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); | |
| 10687 | + } | |
| 10993 | 10688 | } |
| 10994 | 10689 | }else{ |
| 10995 | 10690 | *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", |
| 10996 | 10691 | (int)pNew->cds.iOffset |
| 10997 | 10692 | ); |
| @@ -11774,10 +11469,15 @@ | ||
| 11774 | 11469 | |
| 11775 | 11470 | if( rc==SQLITE_OK ){ |
| 11776 | 11471 | zPath = (const char*)sqlite3_value_text(apVal[2]); |
| 11777 | 11472 | if( zPath==0 ) zPath = ""; |
| 11778 | 11473 | nPath = (int)strlen(zPath); |
| 11474 | + if( nPath>ZIPFILE_MX_NAME ){ | |
| 11475 | + zipfileTableErr(pTab, "filename too long; max: %d bytes", | |
| 11476 | + ZIPFILE_MX_NAME); | |
| 11477 | + rc = SQLITE_CONSTRAINT; | |
| 11478 | + } | |
| 11779 | 11479 | mTime = zipfileGetTime(apVal[4]); |
| 11780 | 11480 | } |
| 11781 | 11481 | |
| 11782 | 11482 | if( rc==SQLITE_OK && bIsDir ){ |
| 11783 | 11483 | /* For a directory, check that the last character in the path is a |
| @@ -12135,10 +11835,17 @@ | ||
| 12135 | 11835 | if( zName==0 ){ |
| 12136 | 11836 | zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL"); |
| 12137 | 11837 | rc = SQLITE_ERROR; |
| 12138 | 11838 | goto zipfile_step_out; |
| 12139 | 11839 | } |
| 11840 | + if( nName>ZIPFILE_MX_NAME ){ | |
| 11841 | + zErr = sqlite3_mprintf( | |
| 11842 | + "filename argument to zipfile() too big; max: %d bytes", | |
| 11843 | + ZIPFILE_MX_NAME); | |
| 11844 | + rc = SQLITE_ERROR; | |
| 11845 | + goto zipfile_step_out; | |
| 11846 | + } | |
| 12140 | 11847 | |
| 12141 | 11848 | /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use |
| 12142 | 11849 | ** deflate compression) or NULL (choose automatically). */ |
| 12143 | 11850 | if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ |
| 12144 | 11851 | iMethod = (int)sqlite3_value_int64(pMethod); |
| @@ -12477,10 +12184,11 @@ | ||
| 12477 | 12184 | return rc; |
| 12478 | 12185 | } |
| 12479 | 12186 | |
| 12480 | 12187 | /************************* End ../ext/misc/sqlar.c ********************/ |
| 12481 | 12188 | #endif |
| 12189 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 12482 | 12190 | /************************* Begin ../ext/expert/sqlite3expert.h ******************/ |
| 12483 | 12191 | /* |
| 12484 | 12192 | ** 2017 April 07 |
| 12485 | 12193 | ** |
| 12486 | 12194 | ** The author disclaims copyright to this source code. In place of |
| @@ -14885,10 +14593,11 @@ | ||
| 14885 | 14593 | } |
| 14886 | 14594 | |
| 14887 | 14595 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
| 14888 | 14596 | |
| 14889 | 14597 | /************************* End ../ext/expert/sqlite3expert.c ********************/ |
| 14598 | +#endif | |
| 14890 | 14599 | /************************* Begin ../ext/intck/sqlite3intck.h ******************/ |
| 14891 | 14600 | /* |
| 14892 | 14601 | ** 2024-02-08 |
| 14893 | 14602 | ** |
| 14894 | 14603 | ** The author disclaims copyright to this source code. In place of |
| @@ -21525,15 +21234,17 @@ | ||
| 21525 | 21234 | char **azFilter; /* Array of xFilter rejection GLOB patterns */ |
| 21526 | 21235 | sqlite3_session *p; /* The open session */ |
| 21527 | 21236 | }; |
| 21528 | 21237 | #endif |
| 21529 | 21238 | |
| 21239 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 21530 | 21240 | typedef struct ExpertInfo ExpertInfo; |
| 21531 | 21241 | struct ExpertInfo { |
| 21532 | 21242 | sqlite3expert *pExpert; |
| 21533 | 21243 | int bVerbose; |
| 21534 | 21244 | }; |
| 21245 | +#endif | |
| 21535 | 21246 | |
| 21536 | 21247 | /* A single line in the EQP output */ |
| 21537 | 21248 | typedef struct EQPGraphRow EQPGraphRow; |
| 21538 | 21249 | struct EQPGraphRow { |
| 21539 | 21250 | int iEqpId; /* ID for this row */ |
| @@ -21633,11 +21344,13 @@ | ||
| 21633 | 21344 | int *aiIndent; /* Array of indents used in MODE_Explain */ |
| 21634 | 21345 | int nIndent; /* Size of array aiIndent[] */ |
| 21635 | 21346 | int iIndent; /* Index of current op in aiIndent[] */ |
| 21636 | 21347 | char *zNonce; /* Nonce for temporary safe-mode escapes */ |
| 21637 | 21348 | EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ |
| 21349 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 21638 | 21350 | ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ |
| 21351 | +#endif | |
| 21639 | 21352 | #ifdef SQLITE_SHELL_FIDDLE |
| 21640 | 21353 | struct { |
| 21641 | 21354 | const char * zInput; /* Input string from wasm/JS proxy */ |
| 21642 | 21355 | const char * zPos; /* Cursor pos into zInput */ |
| 21643 | 21356 | const char * zDefaultDbName; /* Default name for db file */ |
| @@ -21661,13 +21374,12 @@ | ||
| 21661 | 21374 | */ |
| 21662 | 21375 | #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ |
| 21663 | 21376 | #define SHELL_OPEN_NORMAL 1 /* Normal database file */ |
| 21664 | 21377 | #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ |
| 21665 | 21378 | #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ |
| 21666 | -#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ | |
| 21667 | -#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ | |
| 21668 | -#define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */ | |
| 21379 | +#define SHELL_OPEN_DESERIALIZE 4 /* Open using sqlite3_deserialize() */ | |
| 21380 | +#define SHELL_OPEN_HEXDB 5 /* Use "dbtotxt" output as data source */ | |
| 21669 | 21381 | |
| 21670 | 21382 | /* Allowed values for ShellState.eTraceType |
| 21671 | 21383 | */ |
| 21672 | 21384 | #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ |
| 21673 | 21385 | #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ |
| @@ -22006,11 +21718,11 @@ | ||
| 22006 | 21718 | */ |
| 22007 | 21719 | static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ |
| 22008 | 21720 | int i; |
| 22009 | 21721 | unsigned char *aBlob = (unsigned char*)pBlob; |
| 22010 | 21722 | |
| 22011 | - char *zStr = sqlite3_malloc(nBlob*2 + 1); | |
| 21723 | + char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1); | |
| 22012 | 21724 | shell_check_oom(zStr); |
| 22013 | 21725 | |
| 22014 | 21726 | for(i=0; i<nBlob; i++){ |
| 22015 | 21727 | static const char aHex[] = { |
| 22016 | 21728 | '0', '1', '2', '3', '4', '5', '6', '7', |
| @@ -22027,11 +21739,11 @@ | ||
| 22027 | 21739 | |
| 22028 | 21740 | /* |
| 22029 | 21741 | ** Output the given string as a quoted string using SQL quoting conventions: |
| 22030 | 21742 | ** |
| 22031 | 21743 | ** (1) Single quotes (') within the string are doubled |
| 22032 | -** (2) The whle string is enclosed in '...' | |
| 21744 | +** (2) The while string is enclosed in '...' | |
| 22033 | 21745 | ** (3) Control characters other than \n, \t, and \r\n are escaped |
| 22034 | 21746 | ** using \u00XX notation and if such substitutions occur, |
| 22035 | 21747 | ** the whole string is enclosed in unistr('...') instead of '...'. |
| 22036 | 21748 | ** |
| 22037 | 21749 | ** Step (3) is omitted if the control-character escape mode is OFF. |
| @@ -22273,11 +21985,11 @@ | ||
| 22273 | 21985 | ** |
| 22274 | 21986 | ** Escaping is needed if the string contains any control characters |
| 22275 | 21987 | ** other than \t, \n, and \r\n |
| 22276 | 21988 | ** |
| 22277 | 21989 | ** If no escaping is needed (the common case) then set *ppFree to NULL |
| 22278 | -** and return the original string. If escapingn is needed, write the | |
| 21990 | +** and return the original string. If escaping is needed, write the | |
| 22279 | 21991 | ** escaped string into memory obtained from sqlite3_malloc64() or the |
| 22280 | 21992 | ** equivalent, and return the new string and set *ppFree to the new string |
| 22281 | 21993 | ** as well. |
| 22282 | 21994 | ** |
| 22283 | 21995 | ** The caller is responsible for freeing *ppFree if it is non-NULL in order |
| @@ -23278,32 +22990,21 @@ | ||
| 23278 | 22990 | ** Set the destination table field of the ShellState structure to |
| 23279 | 22991 | ** the name of the table given. Escape any quote characters in the |
| 23280 | 22992 | ** table name. |
| 23281 | 22993 | */ |
| 23282 | 22994 | static void set_table_name(ShellState *p, const char *zName){ |
| 23283 | - int i, n; | |
| 23284 | - char cQuote; | |
| 23285 | - char *z; | |
| 23286 | - | |
| 23287 | 22995 | if( p->zDestTable ){ |
| 23288 | - free(p->zDestTable); | |
| 22996 | + sqlite3_free(p->zDestTable); | |
| 23289 | 22997 | p->zDestTable = 0; |
| 23290 | 22998 | } |
| 23291 | 22999 | if( zName==0 ) return; |
| 23292 | - cQuote = quoteChar(zName); | |
| 23293 | - n = strlen30(zName); | |
| 23294 | - if( cQuote ) n += n+2; | |
| 23295 | - z = p->zDestTable = malloc( n+1 ); | |
| 23296 | - shell_check_oom(z); | |
| 23297 | - n = 0; | |
| 23298 | - if( cQuote ) z[n++] = cQuote; | |
| 23299 | - for(i=0; zName[i]; i++){ | |
| 23300 | - z[n++] = zName[i]; | |
| 23301 | - if( zName[i]==cQuote ) z[n++] = cQuote; | |
| 23302 | - } | |
| 23303 | - if( cQuote ) z[n++] = cQuote; | |
| 23304 | - z[n] = 0; | |
| 23000 | + if( quoteChar(zName) ){ | |
| 23001 | + p->zDestTable = sqlite3_mprintf("\"%w\"", zName); | |
| 23002 | + }else{ | |
| 23003 | + p->zDestTable = sqlite3_mprintf("%s", zName); | |
| 23004 | + } | |
| 23005 | + shell_check_oom(p->zDestTable); | |
| 23305 | 23006 | } |
| 23306 | 23007 | |
| 23307 | 23008 | /* |
| 23308 | 23009 | ** Maybe construct two lines of text that point out the position of a |
| 23309 | 23010 | ** syntax error. Return a pointer to the text, in memory obtained from |
| @@ -23496,12 +23197,12 @@ | ||
| 23496 | 23197 | static int display_stats( |
| 23497 | 23198 | sqlite3 *db, /* Database to query */ |
| 23498 | 23199 | ShellState *pArg, /* Pointer to ShellState */ |
| 23499 | 23200 | int bReset /* True to reset the stats */ |
| 23500 | 23201 | ){ |
| 23501 | - int iCur; | |
| 23502 | - int iHiwtr; | |
| 23202 | + int iCur, iHiwtr; | |
| 23203 | + sqlite3_int64 iCur64, iHiwtr64; | |
| 23503 | 23204 | FILE *out; |
| 23504 | 23205 | if( pArg==0 || pArg->out==0 ) return 0; |
| 23505 | 23206 | out = pArg->out; |
| 23506 | 23207 | |
| 23507 | 23208 | if( pArg->pStmt && pArg->statsOn==2 ){ |
| @@ -23586,18 +23287,25 @@ | ||
| 23586 | 23287 | "Page cache hits: %d\n", iCur); |
| 23587 | 23288 | iHiwtr = iCur = -1; |
| 23588 | 23289 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); |
| 23589 | 23290 | sqlite3_fprintf(out, |
| 23590 | 23291 | "Page cache misses: %d\n", iCur); |
| 23292 | + iHiwtr64 = iCur64 = -1; | |
| 23293 | + sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64, | |
| 23294 | + 0); | |
| 23591 | 23295 | iHiwtr = iCur = -1; |
| 23592 | 23296 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); |
| 23593 | 23297 | sqlite3_fprintf(out, |
| 23594 | 23298 | "Page cache writes: %d\n", iCur); |
| 23595 | 23299 | iHiwtr = iCur = -1; |
| 23596 | 23300 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); |
| 23597 | 23301 | sqlite3_fprintf(out, |
| 23598 | 23302 | "Page cache spills: %d\n", iCur); |
| 23303 | + sqlite3_fprintf(out, | |
| 23304 | + "Temporary data spilled to disk: %lld\n", iCur64); | |
| 23305 | + sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64, | |
| 23306 | + 1); | |
| 23599 | 23307 | iHiwtr = iCur = -1; |
| 23600 | 23308 | sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); |
| 23601 | 23309 | sqlite3_fprintf(out, |
| 23602 | 23310 | "Schema Heap Usage: %d bytes\n", iCur); |
| 23603 | 23311 | iHiwtr = iCur = -1; |
| @@ -23999,10 +23707,40 @@ | ||
| 23999 | 23707 | char *zBuf = sqlite3_malloc64( szVar-5 ); |
| 24000 | 23708 | if( zBuf ){ |
| 24001 | 23709 | memcpy(zBuf, &zVar[6], szVar-5); |
| 24002 | 23710 | sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8); |
| 24003 | 23711 | } |
| 23712 | +#ifdef SQLITE_ENABLE_CARRAY | |
| 23713 | + }else if( strncmp(zVar, "$carray_", 8)==0 ){ | |
| 23714 | + static char *azColorNames[] = { | |
| 23715 | + "azure", "black", "blue", "brown", "cyan", "fuchsia", "gold", | |
| 23716 | + "gray", "green", "indigo", "khaki", "lime", "magenta", "maroon", | |
| 23717 | + "navy", "olive", "orange", "pink", "purple", "red", "silver", | |
| 23718 | + "tan", "teal", "violet", "white", "yellow" | |
| 23719 | + }; | |
| 23720 | + static int aPrimes[] = { | |
| 23721 | + 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, | |
| 23722 | + 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 | |
| 23723 | + }; | |
| 23724 | + /* Special bindings: carray($carray_clr), carray($carray_primes) | |
| 23725 | + ** with --unsafe-testing: carray($carray_clr_p,26,'char*'), | |
| 23726 | + ** carray($carray_primes_p,26,'int32') | |
| 23727 | + */ | |
| 23728 | + if( strcmp(zVar+8,"clr")==0 ){ | |
| 23729 | + sqlite3_carray_bind(pStmt,i,azColorNames,26,SQLITE_CARRAY_TEXT,0); | |
| 23730 | + }else if( strcmp(zVar+8,"primes")==0 ){ | |
| 23731 | + sqlite3_carray_bind(pStmt,i,aPrimes,26,SQLITE_CARRAY_INT32,0); | |
| 23732 | + }else if( strcmp(zVar+8,"clr_p")==0 | |
| 23733 | + && ShellHasFlag(pArg,SHFLG_TestingMode) ){ | |
| 23734 | + sqlite3_bind_pointer(pStmt,i,azColorNames,"carray",0); | |
| 23735 | + }else if( strcmp(zVar+8,"primes_p")==0 | |
| 23736 | + && ShellHasFlag(pArg,SHFLG_TestingMode) ){ | |
| 23737 | + sqlite3_bind_pointer(pStmt,i,aPrimes,"carray",0); | |
| 23738 | + }else{ | |
| 23739 | + sqlite3_bind_null(pStmt, i); | |
| 23740 | + } | |
| 23741 | +#endif | |
| 24004 | 23742 | }else{ |
| 24005 | 23743 | sqlite3_bind_null(pStmt, i); |
| 24006 | 23744 | } |
| 24007 | 23745 | sqlite3_reset(pQ); |
| 24008 | 23746 | } |
| @@ -24581,11 +24319,11 @@ | ||
| 24581 | 24319 | } |
| 24582 | 24320 | } |
| 24583 | 24321 | } |
| 24584 | 24322 | } |
| 24585 | 24323 | |
| 24586 | -#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 24324 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 24587 | 24325 | /* |
| 24588 | 24326 | ** This function is called to process SQL if the previous shell command |
| 24589 | 24327 | ** was ".expert". It passes the SQL in the second argument directly to |
| 24590 | 24328 | ** the sqlite3expert object. |
| 24591 | 24329 | ** |
| @@ -24713,11 +24451,11 @@ | ||
| 24713 | 24451 | } |
| 24714 | 24452 | sqlite3_free(zErr); |
| 24715 | 24453 | |
| 24716 | 24454 | return rc; |
| 24717 | 24455 | } |
| 24718 | -#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ | |
| 24456 | +#endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */ | |
| 24719 | 24457 | |
| 24720 | 24458 | /* |
| 24721 | 24459 | ** Execute a statement or set of statements. Print |
| 24722 | 24460 | ** any result rows/columns depending on the current mode |
| 24723 | 24461 | ** set via the supplied callback. |
| @@ -24739,11 +24477,11 @@ | ||
| 24739 | 24477 | |
| 24740 | 24478 | if( pzErrMsg ){ |
| 24741 | 24479 | *pzErrMsg = NULL; |
| 24742 | 24480 | } |
| 24743 | 24481 | |
| 24744 | -#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 24482 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 24745 | 24483 | if( pArg->expert.pExpert ){ |
| 24746 | 24484 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
| 24747 | 24485 | return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); |
| 24748 | 24486 | } |
| 24749 | 24487 | #endif |
| @@ -24901,11 +24639,11 @@ | ||
| 24901 | 24639 | static char **tableColumnList(ShellState *p, const char *zTab){ |
| 24902 | 24640 | char **azCol = 0; |
| 24903 | 24641 | sqlite3_stmt *pStmt; |
| 24904 | 24642 | char *zSql; |
| 24905 | 24643 | int nCol = 0; |
| 24906 | - int nAlloc = 0; | |
| 24644 | + i64 nAlloc = 0; | |
| 24907 | 24645 | int nPK = 0; /* Number of PRIMARY KEY columns seen */ |
| 24908 | 24646 | int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ |
| 24909 | 24647 | int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); |
| 24910 | 24648 | int rc; |
| 24911 | 24649 | |
| @@ -24915,11 +24653,11 @@ | ||
| 24915 | 24653 | sqlite3_free(zSql); |
| 24916 | 24654 | if( rc ) return 0; |
| 24917 | 24655 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 24918 | 24656 | if( nCol>=nAlloc-2 ){ |
| 24919 | 24657 | nAlloc = nAlloc*2 + nCol + 10; |
| 24920 | - azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); | |
| 24658 | + azCol = sqlite3_realloc64(azCol, nAlloc*sizeof(azCol[0])); | |
| 24921 | 24659 | shell_check_oom(azCol); |
| 24922 | 24660 | } |
| 24923 | 24661 | azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); |
| 24924 | 24662 | shell_check_oom(azCol[nCol]); |
| 24925 | 24663 | if( sqlite3_column_int(pStmt, 5) ){ |
| @@ -25106,17 +24844,17 @@ | ||
| 25106 | 24844 | appendText(&sSelect, " FROM ", 0); |
| 25107 | 24845 | appendText(&sSelect, zTable, quoteChar(zTable)); |
| 25108 | 24846 | |
| 25109 | 24847 | savedDestTable = p->zDestTable; |
| 25110 | 24848 | savedMode = p->mode; |
| 25111 | - p->zDestTable = sTable.z; | |
| 24849 | + p->zDestTable = sTable.zTxt; | |
| 25112 | 24850 | p->mode = p->cMode = MODE_Insert; |
| 25113 | - rc = shell_exec(p, sSelect.z, 0); | |
| 24851 | + rc = shell_exec(p, sSelect.zTxt, 0); | |
| 25114 | 24852 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
| 25115 | 24853 | sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); |
| 25116 | 24854 | toggleSelectOrder(p->db); |
| 25117 | - shell_exec(p, sSelect.z, 0); | |
| 24855 | + shell_exec(p, sSelect.zTxt, 0); | |
| 25118 | 24856 | toggleSelectOrder(p->db); |
| 25119 | 24857 | } |
| 25120 | 24858 | p->zDestTable = savedDestTable; |
| 25121 | 24859 | p->mode = savedMode; |
| 25122 | 24860 | freeText(&sTable); |
| @@ -25245,11 +24983,13 @@ | ||
| 25245 | 24983 | " --bom Put a UTF8 byte-order mark on intermediate file", |
| 25246 | 24984 | #endif |
| 25247 | 24985 | #ifndef SQLITE_SHELL_FIDDLE |
| 25248 | 24986 | ".exit ?CODE? Exit this program with return-code CODE", |
| 25249 | 24987 | #endif |
| 24988 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 25250 | 24989 | ".expert EXPERIMENTAL. Suggest indexes for queries", |
| 24990 | +#endif | |
| 25251 | 24991 | ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto", |
| 25252 | 24992 | ".filectrl CMD ... Run various sqlite3_file_control() operations", |
| 25253 | 24993 | " --schema SCHEMA Use SCHEMA instead of \"main\"", |
| 25254 | 24994 | " --help Show CMD details", |
| 25255 | 24995 | ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", |
| @@ -25270,11 +25010,11 @@ | ||
| 25270 | 25010 | " from the \".mode\" output mode", |
| 25271 | 25011 | " * If FILE begins with \"|\" then it is a command that generates the", |
| 25272 | 25012 | " input text.", |
| 25273 | 25013 | #endif |
| 25274 | 25014 | #ifndef SQLITE_OMIT_TEST_CONTROL |
| 25275 | - ",imposter INDEX TABLE Create imposter table TABLE on index INDEX", | |
| 25015 | + ".imposter INDEX TABLE Create imposter table TABLE on index INDEX", | |
| 25276 | 25016 | #endif |
| 25277 | 25017 | ".indexes ?TABLE? Show names of indexes", |
| 25278 | 25018 | " If TABLE is specified, only show indexes for", |
| 25279 | 25019 | " tables matching TABLE using the LIKE operator.", |
| 25280 | 25020 | ".intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db", |
| @@ -25337,11 +25077,17 @@ | ||
| 25337 | 25077 | " Options:", |
| 25338 | 25078 | " --append Use appendvfs to append database to the end of FILE", |
| 25339 | 25079 | #endif |
| 25340 | 25080 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 25341 | 25081 | " --deserialize Load into memory using sqlite3_deserialize()", |
| 25082 | +#endif | |
| 25083 | +/*" --exclusive Set the SQLITE_OPEN_EXCLUSIVE flag", UNDOCUMENTED */ | |
| 25084 | +#ifndef SQLITE_OMIT_DESERIALIZE | |
| 25342 | 25085 | " --hexdb Load the output of \"dbtotxt\" as an in-memory db", |
| 25086 | +#endif | |
| 25087 | + " --ifexist Only open if FILE already exists", | |
| 25088 | +#ifndef SQLITE_OMIT_DESERIALIZE | |
| 25343 | 25089 | " --maxsize N Maximum size for --hexdb or --deserialized database", |
| 25344 | 25090 | #endif |
| 25345 | 25091 | " --new Initialize FILE to an empty database", |
| 25346 | 25092 | " --nofollow Do not follow symbolic links", |
| 25347 | 25093 | " --readonly Open FILE readonly", |
| @@ -25726,14 +25472,14 @@ | ||
| 25726 | 25472 | ** If p->aAuxDb[].zDbFilename is 0, then read from standard input. |
| 25727 | 25473 | */ |
| 25728 | 25474 | static unsigned char *readHexDb(ShellState *p, int *pnData){ |
| 25729 | 25475 | unsigned char *a = 0; |
| 25730 | 25476 | int nLine; |
| 25731 | - int n = 0; | |
| 25477 | + int n = 0; /* Size of db per first line of hex dump */ | |
| 25478 | + i64 sz = 0; /* n rounded up to nearest page boundary */ | |
| 25732 | 25479 | int pgsz = 0; |
| 25733 | - int iOffset = 0; | |
| 25734 | - int j, k; | |
| 25480 | + i64 iOffset = 0; | |
| 25735 | 25481 | int rc; |
| 25736 | 25482 | FILE *in; |
| 25737 | 25483 | const char *zDbFilename = p->pAuxDb->zDbFilename; |
| 25738 | 25484 | unsigned int x[16]; |
| 25739 | 25485 | char zLine[1000]; |
| @@ -25753,20 +25499,21 @@ | ||
| 25753 | 25499 | nLine++; |
| 25754 | 25500 | if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; |
| 25755 | 25501 | rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); |
| 25756 | 25502 | if( rc!=2 ) goto readHexDb_error; |
| 25757 | 25503 | if( n<0 ) goto readHexDb_error; |
| 25758 | - if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; | |
| 25759 | - n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ | |
| 25760 | - a = sqlite3_malloc( n ? n : 1 ); | |
| 25761 | - shell_check_oom(a); | |
| 25762 | - memset(a, 0, n); | |
| 25763 | 25504 | if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
| 25764 | 25505 | sqlite3_fputs("invalid pagesize\n", stderr); |
| 25765 | 25506 | goto readHexDb_error; |
| 25766 | 25507 | } |
| 25508 | + sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */ | |
| 25509 | + a = sqlite3_malloc64( sz ? sz : 1 ); | |
| 25510 | + shell_check_oom(a); | |
| 25511 | + memset(a, 0, sz); | |
| 25767 | 25512 | for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
| 25513 | + int j = 0; /* Page number from "| page" line */ | |
| 25514 | + int k = 0; /* Offset from "| page" line */ | |
| 25768 | 25515 | rc = sscanf(zLine, "| page %d offset %d", &j, &k); |
| 25769 | 25516 | if( rc==2 ){ |
| 25770 | 25517 | iOffset = k; |
| 25771 | 25518 | continue; |
| 25772 | 25519 | } |
| @@ -25775,18 +25522,18 @@ | ||
| 25775 | 25522 | } |
| 25776 | 25523 | rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", |
| 25777 | 25524 | &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], |
| 25778 | 25525 | &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); |
| 25779 | 25526 | if( rc==17 ){ |
| 25780 | - k = iOffset+j; | |
| 25781 | - if( k+16<=n && k>=0 ){ | |
| 25527 | + i64 iOff = iOffset+j; | |
| 25528 | + if( iOff+16<=sz && iOff>=0 ){ | |
| 25782 | 25529 | int ii; |
| 25783 | - for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff; | |
| 25530 | + for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff; | |
| 25784 | 25531 | } |
| 25785 | 25532 | } |
| 25786 | 25533 | } |
| 25787 | - *pnData = n; | |
| 25534 | + *pnData = sz; | |
| 25788 | 25535 | if( in!=p->in ){ |
| 25789 | 25536 | fclose(in); |
| 25790 | 25537 | }else{ |
| 25791 | 25538 | p->lineno = nLine; |
| 25792 | 25539 | } |
| @@ -25849,11 +25596,11 @@ | ||
| 25849 | 25596 | p->pLog = pSavedLog; |
| 25850 | 25597 | |
| 25851 | 25598 | if( zFake ){ |
| 25852 | 25599 | sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), |
| 25853 | 25600 | -1, sqlite3_free); |
| 25854 | - free(zFake); | |
| 25601 | + sqlite3_free(zFake); | |
| 25855 | 25602 | } |
| 25856 | 25603 | } |
| 25857 | 25604 | |
| 25858 | 25605 | /* Flags for open_db(). |
| 25859 | 25606 | ** |
| @@ -25881,14 +25628,17 @@ | ||
| 25881 | 25628 | }else{ |
| 25882 | 25629 | p->openMode = (u8)deduceDatabaseType(zDbFilename, |
| 25883 | 25630 | (openFlags & OPEN_DB_ZIPFILE)!=0); |
| 25884 | 25631 | } |
| 25885 | 25632 | } |
| 25633 | + if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){ | |
| 25634 | + if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE; | |
| 25635 | + p->openFlags |= SQLITE_OPEN_READWRITE; | |
| 25636 | + } | |
| 25886 | 25637 | switch( p->openMode ){ |
| 25887 | 25638 | case SHELL_OPEN_APPENDVFS: { |
| 25888 | - sqlite3_open_v2(zDbFilename, &p->db, | |
| 25889 | - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs"); | |
| 25639 | + sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, "apndvfs"); | |
| 25890 | 25640 | break; |
| 25891 | 25641 | } |
| 25892 | 25642 | case SHELL_OPEN_HEXDB: |
| 25893 | 25643 | case SHELL_OPEN_DESERIALIZE: { |
| 25894 | 25644 | sqlite3_open(0, &p->db); |
| @@ -25896,19 +25646,13 @@ | ||
| 25896 | 25646 | } |
| 25897 | 25647 | case SHELL_OPEN_ZIPFILE: { |
| 25898 | 25648 | sqlite3_open(":memory:", &p->db); |
| 25899 | 25649 | break; |
| 25900 | 25650 | } |
| 25901 | - case SHELL_OPEN_READONLY: { | |
| 25902 | - sqlite3_open_v2(zDbFilename, &p->db, | |
| 25903 | - SQLITE_OPEN_READONLY|p->openFlags, 0); | |
| 25904 | - break; | |
| 25905 | - } | |
| 25906 | 25651 | case SHELL_OPEN_UNSPEC: |
| 25907 | 25652 | case SHELL_OPEN_NORMAL: { |
| 25908 | - sqlite3_open_v2(zDbFilename, &p->db, | |
| 25909 | - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); | |
| 25653 | + sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0); | |
| 25910 | 25654 | break; |
| 25911 | 25655 | } |
| 25912 | 25656 | } |
| 25913 | 25657 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
| 25914 | 25658 | sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
| @@ -25944,11 +25688,10 @@ | ||
| 25944 | 25688 | sqlite3_sha_init(p->db, 0, 0); |
| 25945 | 25689 | sqlite3_shathree_init(p->db, 0, 0); |
| 25946 | 25690 | sqlite3_uint_init(p->db, 0, 0); |
| 25947 | 25691 | sqlite3_stmtrand_init(p->db, 0, 0); |
| 25948 | 25692 | sqlite3_decimal_init(p->db, 0, 0); |
| 25949 | - sqlite3_percentile_init(p->db, 0, 0); | |
| 25950 | 25693 | sqlite3_base64_init(p->db, 0, 0); |
| 25951 | 25694 | sqlite3_base85_init(p->db, 0, 0); |
| 25952 | 25695 | sqlite3_regexp_init(p->db, 0, 0); |
| 25953 | 25696 | sqlite3_ieee_init(p->db, 0, 0); |
| 25954 | 25697 | sqlite3_series_init(p->db, 0, 0); |
| @@ -26043,13 +25786,15 @@ | ||
| 26043 | 25786 | } |
| 26044 | 25787 | } |
| 26045 | 25788 | #endif |
| 26046 | 25789 | } |
| 26047 | 25790 | if( p->db!=0 ){ |
| 25791 | +#ifndef SQLITE_OMIT_AUTHORIZATION | |
| 26048 | 25792 | if( p->bSafeModePersist ){ |
| 26049 | 25793 | sqlite3_set_authorizer(p->db, safeModeAuth, p); |
| 26050 | 25794 | } |
| 25795 | +#endif | |
| 26051 | 25796 | sqlite3_db_config( |
| 26052 | 25797 | p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0 |
| 26053 | 25798 | ); |
| 26054 | 25799 | } |
| 26055 | 25800 | } |
| @@ -26358,12 +26103,12 @@ | ||
| 26358 | 26103 | struct ImportCtx { |
| 26359 | 26104 | const char *zFile; /* Name of the input file */ |
| 26360 | 26105 | FILE *in; /* Read the CSV text from this input stream */ |
| 26361 | 26106 | int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */ |
| 26362 | 26107 | char *z; /* Accumulated text for a field */ |
| 26363 | - int n; /* Number of bytes in z */ | |
| 26364 | - int nAlloc; /* Space allocated for z[] */ | |
| 26108 | + i64 n; /* Number of bytes in z */ | |
| 26109 | + i64 nAlloc; /* Space allocated for z[] */ | |
| 26365 | 26110 | int nLine; /* Current line number */ |
| 26366 | 26111 | int nRow; /* Number of rows imported */ |
| 26367 | 26112 | int nErr; /* Number of errors encountered */ |
| 26368 | 26113 | int bNotFirst; /* True if one or more bytes already read */ |
| 26369 | 26114 | int cTerm; /* Character that terminated the most recent field */ |
| @@ -26829,14 +26574,17 @@ | ||
| 26829 | 26574 | #if SQLITE_SHELL_HAVE_RECOVER |
| 26830 | 26575 | /* |
| 26831 | 26576 | ** Convert a 2-byte or 4-byte big-endian integer into a native integer |
| 26832 | 26577 | */ |
| 26833 | 26578 | static unsigned int get2byteInt(unsigned char *a){ |
| 26834 | - return (a[0]<<8) + a[1]; | |
| 26579 | + return ((unsigned int)a[0]<<8) + (unsigned int)a[1]; | |
| 26835 | 26580 | } |
| 26836 | 26581 | static unsigned int get4byteInt(unsigned char *a){ |
| 26837 | - return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; | |
| 26582 | + return ((unsigned int)a[0]<<24) | |
| 26583 | + + ((unsigned int)a[1]<<16) | |
| 26584 | + + ((unsigned int)a[2]<<8) | |
| 26585 | + + (unsigned int)a[3]; | |
| 26838 | 26586 | } |
| 26839 | 26587 | |
| 26840 | 26588 | /* |
| 26841 | 26589 | ** Implementation of the ".dbinfo" command. |
| 26842 | 26590 | ** |
| @@ -26969,11 +26717,11 @@ | ||
| 26969 | 26717 | if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; |
| 26970 | 26718 | nPage = sqlite3_column_int64(pStmt, 0); |
| 26971 | 26719 | sqlite3_finalize(pStmt); |
| 26972 | 26720 | pStmt = 0; |
| 26973 | 26721 | if( nPage<1 ) goto dbtotxt_error; |
| 26974 | - rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0); | |
| 26722 | + rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); | |
| 26975 | 26723 | if( rc ) goto dbtotxt_error; |
| 26976 | 26724 | if( sqlite3_step(pStmt)!=SQLITE_ROW ){ |
| 26977 | 26725 | zTail = "unk.db"; |
| 26978 | 26726 | }else{ |
| 26979 | 26727 | const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2); |
| @@ -26980,10 +26728,15 @@ | ||
| 26980 | 26728 | if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; |
| 26981 | 26729 | zTail = strrchr(zFilename, '/'); |
| 26982 | 26730 | #if defined(_WIN32) |
| 26983 | 26731 | if( zTail==0 ) zTail = strrchr(zFilename, '\\'); |
| 26984 | 26732 | #endif |
| 26733 | + if( zTail==0 ){ | |
| 26734 | + zTail = zFilename; | |
| 26735 | + }else if( zTail[1]!=0 ){ | |
| 26736 | + zTail++; | |
| 26737 | + } | |
| 26985 | 26738 | } |
| 26986 | 26739 | zName = strdup(zTail); |
| 26987 | 26740 | shell_check_oom(zName); |
| 26988 | 26741 | sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", |
| 26989 | 26742 | nPage*pgSz, pgSz, zName); |
| @@ -27148,10 +26901,47 @@ | ||
| 27148 | 26901 | if( zStr[0]!='-' ) return 0; |
| 27149 | 26902 | zStr++; |
| 27150 | 26903 | if( zStr[0]=='-' ) zStr++; |
| 27151 | 26904 | return cli_strcmp(zStr, zOpt)==0; |
| 27152 | 26905 | } |
| 26906 | + | |
| 26907 | +/* | |
| 26908 | +** The input zFN is guaranteed to start with "file:" and is thus a URI | |
| 26909 | +** filename. Extract the actual filename and return a pointer to that | |
| 26910 | +** filename in spaced obtained from sqlite3_malloc(). | |
| 26911 | +** | |
| 26912 | +** The caller is responsible for freeing space using sqlite3_free() when | |
| 26913 | +** it has finished with the filename. | |
| 26914 | +*/ | |
| 26915 | +static char *shellFilenameFromUri(const char *zFN){ | |
| 26916 | + char *zOut; | |
| 26917 | + int i, j, d1, d2; | |
| 26918 | + | |
| 26919 | + assert( cli_strncmp(zFN,"file:",5)==0 ); | |
| 26920 | + zOut = sqlite3_mprintf("%s", zFN+5); | |
| 26921 | + shell_check_oom(zOut); | |
| 26922 | + for(i=j=0; zOut[i]!=0 && zOut[i]!='?'; i++){ | |
| 26923 | + if( zOut[i]!='%' ){ | |
| 26924 | + zOut[j++] = zOut[i]; | |
| 26925 | + continue; | |
| 26926 | + } | |
| 26927 | + d1 = hexDigitValue(zOut[i+1]); | |
| 26928 | + if( d1<0 ){ | |
| 26929 | + zOut[j] = 0; | |
| 26930 | + break; | |
| 26931 | + } | |
| 26932 | + d2 = hexDigitValue(zOut[i+2]); | |
| 26933 | + if( d2<0 ){ | |
| 26934 | + zOut[j] = 0; | |
| 26935 | + break; | |
| 26936 | + } | |
| 26937 | + zOut[j++] = d1*16 + d2; | |
| 26938 | + i += 2; | |
| 26939 | + } | |
| 26940 | + zOut[j] = 0; | |
| 26941 | + return zOut; | |
| 26942 | +} | |
| 27153 | 26943 | |
| 27154 | 26944 | /* |
| 27155 | 26945 | ** Delete a file. |
| 27156 | 26946 | */ |
| 27157 | 26947 | int shellDeleteFile(const char *zFilename){ |
| @@ -28704,11 +28494,11 @@ | ||
| 28704 | 28494 | int nArg = 0; |
| 28705 | 28495 | int n, c; |
| 28706 | 28496 | int rc = 0; |
| 28707 | 28497 | char *azArg[52]; |
| 28708 | 28498 | |
| 28709 | -#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 28499 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 28710 | 28500 | if( p->expert.pExpert ){ |
| 28711 | 28501 | expertFinish(p, 1, 0); |
| 28712 | 28502 | } |
| 28713 | 28503 | #endif |
| 28714 | 28504 | |
| @@ -29005,11 +28795,11 @@ | ||
| 29005 | 28795 | }else{ |
| 29006 | 28796 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 29007 | 28797 | const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); |
| 29008 | 28798 | const char *zFile = (const char*)sqlite3_column_text(pStmt,2); |
| 29009 | 28799 | if( zSchema==0 || zFile==0 ) continue; |
| 29010 | - azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*)); | |
| 28800 | + azName = sqlite3_realloc64(azName, (nName+1)*2*sizeof(char*)); | |
| 29011 | 28801 | shell_check_oom(azName); |
| 29012 | 28802 | azName[nName*2] = strdup(zSchema); |
| 29013 | 28803 | azName[nName*2+1] = strdup(zFile); |
| 29014 | 28804 | nName++; |
| 29015 | 28805 | } |
| @@ -29208,10 +28998,11 @@ | ||
| 29208 | 28998 | rc = 1; |
| 29209 | 28999 | } |
| 29210 | 29000 | }else |
| 29211 | 29001 | |
| 29212 | 29002 | if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ |
| 29003 | + open_db(p, 0); | |
| 29213 | 29004 | rc = shell_dbtotxt_command(p, nArg, azArg); |
| 29214 | 29005 | }else |
| 29215 | 29006 | |
| 29216 | 29007 | if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ |
| 29217 | 29008 | if( nArg==2 ){ |
| @@ -29273,11 +29064,11 @@ | ||
| 29273 | 29064 | if( p->mode==MODE_Explain ) p->mode = p->normalMode; |
| 29274 | 29065 | p->autoExplain = 1; |
| 29275 | 29066 | } |
| 29276 | 29067 | }else |
| 29277 | 29068 | |
| 29278 | -#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 29069 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 29279 | 29070 | if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ |
| 29280 | 29071 | if( p->bSafeMode ){ |
| 29281 | 29072 | sqlite3_fprintf(stderr, |
| 29282 | 29073 | "Cannot run experimental commands such as \"%s\" in safe mode\n", |
| 29283 | 29074 | azArg[0]); |
| @@ -29840,16 +29631,10 @@ | ||
| 29840 | 29631 | sqlite3_stmt *pStmt; |
| 29841 | 29632 | int tnum = 0; |
| 29842 | 29633 | int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ |
| 29843 | 29634 | int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ |
| 29844 | 29635 | int i; |
| 29845 | - if( !ShellHasFlag(p,SHFLG_TestingMode) ){ | |
| 29846 | - sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n", | |
| 29847 | - "imposter"); | |
| 29848 | - rc = 1; | |
| 29849 | - goto meta_command_exit; | |
| 29850 | - } | |
| 29851 | 29636 | if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ |
| 29852 | 29637 | eputz("Usage: .imposter INDEX IMPOSTER\n" |
| 29853 | 29638 | " .imposter off\n"); |
| 29854 | 29639 | /* Also allowed, but not documented: |
| 29855 | 29640 | ** |
| @@ -29917,22 +29702,19 @@ | ||
| 29917 | 29702 | if( lenPK==0 ) lenPK = 100000; |
| 29918 | 29703 | zSql = sqlite3_mprintf( |
| 29919 | 29704 | "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID", |
| 29920 | 29705 | azArg[2], zCollist, lenPK, zCollist); |
| 29921 | 29706 | sqlite3_free(zCollist); |
| 29922 | - rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); | |
| 29707 | + rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum); | |
| 29923 | 29708 | if( rc==SQLITE_OK ){ |
| 29924 | 29709 | rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
| 29925 | 29710 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); |
| 29926 | 29711 | if( rc ){ |
| 29927 | 29712 | sqlite3_fprintf(stderr, |
| 29928 | 29713 | "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); |
| 29929 | 29714 | }else{ |
| 29930 | 29715 | sqlite3_fprintf(stdout, "%s;\n", zSql); |
| 29931 | - sqlite3_fprintf(stdout, | |
| 29932 | - "WARNING: writing to an imposter table will corrupt" | |
| 29933 | - " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); | |
| 29934 | 29716 | } |
| 29935 | 29717 | }else{ |
| 29936 | 29718 | sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); |
| 29937 | 29719 | rc = 1; |
| 29938 | 29720 | } |
| @@ -30282,10 +30064,11 @@ | ||
| 30282 | 30064 | const char *zFN = 0; /* Pointer to constant filename */ |
| 30283 | 30065 | char *zNewFilename = 0; /* Name of the database file to open */ |
| 30284 | 30066 | int iName = 1; /* Index in azArg[] of the filename */ |
| 30285 | 30067 | int newFlag = 0; /* True to delete file before opening */ |
| 30286 | 30068 | int openMode = SHELL_OPEN_UNSPEC; |
| 30069 | + int openFlags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; | |
| 30287 | 30070 | |
| 30288 | 30071 | /* Check for command-line arguments */ |
| 30289 | 30072 | for(iName=1; iName<nArg; iName++){ |
| 30290 | 30073 | const char *z = azArg[iName]; |
| 30291 | 30074 | #ifndef SQLITE_SHELL_FIDDLE |
| @@ -30296,13 +30079,18 @@ | ||
| 30296 | 30079 | openMode = SHELL_OPEN_ZIPFILE; |
| 30297 | 30080 | #endif |
| 30298 | 30081 | }else if( optionMatch(z, "append") ){ |
| 30299 | 30082 | openMode = SHELL_OPEN_APPENDVFS; |
| 30300 | 30083 | }else if( optionMatch(z, "readonly") ){ |
| 30301 | - openMode = SHELL_OPEN_READONLY; | |
| 30084 | + openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | |
| 30085 | + openFlags |= SQLITE_OPEN_READONLY; | |
| 30086 | + }else if( optionMatch(z, "exclusive") ){ | |
| 30087 | + openFlags |= SQLITE_OPEN_EXCLUSIVE; | |
| 30088 | + }else if( optionMatch(z, "ifexists") ){ | |
| 30089 | + openFlags &= ~(SQLITE_OPEN_CREATE); | |
| 30302 | 30090 | }else if( optionMatch(z, "nofollow") ){ |
| 30303 | - p->openFlags |= SQLITE_OPEN_NOFOLLOW; | |
| 30091 | + openFlags |= SQLITE_OPEN_NOFOLLOW; | |
| 30304 | 30092 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 30305 | 30093 | }else if( optionMatch(z, "deserialize") ){ |
| 30306 | 30094 | openMode = SHELL_OPEN_DESERIALIZE; |
| 30307 | 30095 | }else if( optionMatch(z, "hexdb") ){ |
| 30308 | 30096 | openMode = SHELL_OPEN_HEXDB; |
| @@ -30330,16 +30118,25 @@ | ||
| 30330 | 30118 | p->db = 0; |
| 30331 | 30119 | p->pAuxDb->zDbFilename = 0; |
| 30332 | 30120 | sqlite3_free(p->pAuxDb->zFreeOnClose); |
| 30333 | 30121 | p->pAuxDb->zFreeOnClose = 0; |
| 30334 | 30122 | p->openMode = openMode; |
| 30335 | - p->openFlags = 0; | |
| 30123 | + p->openFlags = openFlags; | |
| 30336 | 30124 | p->szMax = 0; |
| 30337 | 30125 | |
| 30338 | 30126 | /* If a filename is specified, try to open it first */ |
| 30339 | 30127 | if( zFN || p->openMode==SHELL_OPEN_HEXDB ){ |
| 30340 | - if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN); | |
| 30128 | + if( newFlag && zFN && !p->bSafeMode ){ | |
| 30129 | + if( cli_strncmp(zFN,"file:",5)==0 ){ | |
| 30130 | + char *zDel = shellFilenameFromUri(zFN); | |
| 30131 | + shell_check_oom(zDel); | |
| 30132 | + shellDeleteFile(zDel); | |
| 30133 | + sqlite3_free(zDel); | |
| 30134 | + }else{ | |
| 30135 | + shellDeleteFile(zFN); | |
| 30136 | + } | |
| 30137 | + } | |
| 30341 | 30138 | #ifndef SQLITE_SHELL_FIDDLE |
| 30342 | 30139 | if( p->bSafeMode |
| 30343 | 30140 | && p->openMode!=SHELL_OPEN_HEXDB |
| 30344 | 30141 | && zFN |
| 30345 | 30142 | && cli_strcmp(zFN,":memory:")!=0 |
| @@ -30938,13 +30735,13 @@ | ||
| 30938 | 30735 | appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0); |
| 30939 | 30736 | } |
| 30940 | 30737 | appendText(&sSelect, "sql IS NOT NULL" |
| 30941 | 30738 | " ORDER BY snum, rowid", 0); |
| 30942 | 30739 | if( bDebug ){ |
| 30943 | - sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z); | |
| 30740 | + sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt); | |
| 30944 | 30741 | }else{ |
| 30945 | - rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); | |
| 30742 | + rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg); | |
| 30946 | 30743 | } |
| 30947 | 30744 | freeText(&sSelect); |
| 30948 | 30745 | } |
| 30949 | 30746 | if( zErrMsg ){ |
| 30950 | 30747 | shellEmitError(zErrMsg); |
| @@ -31072,19 +30869,20 @@ | ||
| 31072 | 30869 | |
| 31073 | 30870 | /* .session filter GLOB .... |
| 31074 | 30871 | ** Set a list of GLOB patterns of table names to be excluded. |
| 31075 | 30872 | */ |
| 31076 | 30873 | if( cli_strcmp(azCmd[0], "filter")==0 ){ |
| 31077 | - int ii, nByte; | |
| 30874 | + int ii; | |
| 30875 | + i64 nByte; | |
| 31078 | 30876 | if( nCmd<2 ) goto session_syntax_error; |
| 31079 | 30877 | if( pAuxDb->nSession ){ |
| 31080 | 30878 | for(ii=0; ii<pSession->nFilter; ii++){ |
| 31081 | 30879 | sqlite3_free(pSession->azFilter[ii]); |
| 31082 | 30880 | } |
| 31083 | 30881 | sqlite3_free(pSession->azFilter); |
| 31084 | 30882 | nByte = sizeof(pSession->azFilter[0])*(nCmd-1); |
| 31085 | - pSession->azFilter = sqlite3_malloc( nByte ); | |
| 30883 | + pSession->azFilter = sqlite3_malloc64( nByte ); | |
| 31086 | 30884 | shell_check_oom( pSession->azFilter ); |
| 31087 | 30885 | for(ii=1; ii<nCmd; ii++){ |
| 31088 | 30886 | char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); |
| 31089 | 30887 | shell_check_oom(x); |
| 31090 | 30888 | } |
| @@ -31264,26 +31062,26 @@ | ||
| 31264 | 31062 | sqlite3_fprintf(p->out, "%s\n", zSql); |
| 31265 | 31063 | }else |
| 31266 | 31064 | if( cli_strcmp(zOp,"run")==0 ){ |
| 31267 | 31065 | char *zErrMsg = 0; |
| 31268 | 31066 | str.n = 0; |
| 31269 | - str.z[0] = 0; | |
| 31067 | + str.zTxt[0] = 0; | |
| 31270 | 31068 | rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); |
| 31271 | 31069 | nTest++; |
| 31272 | 31070 | if( bVerbose ){ |
| 31273 | - sqlite3_fprintf(p->out, "Result: %s\n", str.z); | |
| 31071 | + sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt); | |
| 31274 | 31072 | } |
| 31275 | 31073 | if( rc || zErrMsg ){ |
| 31276 | 31074 | nErr++; |
| 31277 | 31075 | rc = 1; |
| 31278 | 31076 | sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); |
| 31279 | 31077 | sqlite3_free(zErrMsg); |
| 31280 | - }else if( cli_strcmp(zAns,str.z)!=0 ){ | |
| 31078 | + }else if( cli_strcmp(zAns,str.zTxt)!=0 ){ | |
| 31281 | 31079 | nErr++; |
| 31282 | 31080 | rc = 1; |
| 31283 | 31081 | sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); |
| 31284 | - sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z); | |
| 31082 | + sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt); | |
| 31285 | 31083 | } |
| 31286 | 31084 | } |
| 31287 | 31085 | else{ |
| 31288 | 31086 | sqlite3_fprintf(stderr, |
| 31289 | 31087 | "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); |
| @@ -31395,11 +31193,11 @@ | ||
| 31395 | 31193 | appendText(&sQuery, "SELECT * FROM ", 0); |
| 31396 | 31194 | appendText(&sQuery, zTab, 0); |
| 31397 | 31195 | appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); |
| 31398 | 31196 | } |
| 31399 | 31197 | appendText(&sSql, zSep, 0); |
| 31400 | - appendText(&sSql, sQuery.z, '\''); | |
| 31198 | + appendText(&sSql, sQuery.zTxt, '\''); | |
| 31401 | 31199 | sQuery.n = 0; |
| 31402 | 31200 | appendText(&sSql, ",", 0); |
| 31403 | 31201 | appendText(&sSql, zTab, '\''); |
| 31404 | 31202 | zSep = "),("; |
| 31405 | 31203 | } |
| @@ -31407,17 +31205,17 @@ | ||
| 31407 | 31205 | if( bSeparate ){ |
| 31408 | 31206 | zSql = sqlite3_mprintf( |
| 31409 | 31207 | "%s))" |
| 31410 | 31208 | " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" |
| 31411 | 31209 | " FROM [sha3sum$query]", |
| 31412 | - sSql.z, iSize); | |
| 31210 | + sSql.zTxt, iSize); | |
| 31413 | 31211 | }else{ |
| 31414 | 31212 | zSql = sqlite3_mprintf( |
| 31415 | 31213 | "%s))" |
| 31416 | 31214 | " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" |
| 31417 | 31215 | " FROM [sha3sum$query]", |
| 31418 | - sSql.z, iSize); | |
| 31216 | + sSql.zTxt, iSize); | |
| 31419 | 31217 | } |
| 31420 | 31218 | shell_check_oom(zSql); |
| 31421 | 31219 | freeText(&sQuery); |
| 31422 | 31220 | freeText(&sSql); |
| 31423 | 31221 | if( bDebug ){ |
| @@ -31613,11 +31411,11 @@ | ||
| 31613 | 31411 | goto meta_command_exit; |
| 31614 | 31412 | } |
| 31615 | 31413 | for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ |
| 31616 | 31414 | const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); |
| 31617 | 31415 | if( zDbName==0 ) continue; |
| 31618 | - if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0); | |
| 31416 | + if( s.zTxt && s.zTxt[0] ) appendText(&s, " UNION ALL ", 0); | |
| 31619 | 31417 | if( sqlite3_stricmp(zDbName, "main")==0 ){ |
| 31620 | 31418 | appendText(&s, "SELECT name FROM ", 0); |
| 31621 | 31419 | }else{ |
| 31622 | 31420 | appendText(&s, "SELECT ", 0); |
| 31623 | 31421 | appendText(&s, zDbName, '\''); |
| @@ -31635,11 +31433,11 @@ | ||
| 31635 | 31433 | } |
| 31636 | 31434 | } |
| 31637 | 31435 | rc = sqlite3_finalize(pStmt); |
| 31638 | 31436 | if( rc==SQLITE_OK ){ |
| 31639 | 31437 | appendText(&s, " ORDER BY 1", 0); |
| 31640 | - rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0); | |
| 31438 | + rc = sqlite3_prepare_v2(p->db, s.zTxt, -1, &pStmt, 0); | |
| 31641 | 31439 | } |
| 31642 | 31440 | freeText(&s); |
| 31643 | 31441 | if( rc ) return shellDatabaseError(p->db); |
| 31644 | 31442 | |
| 31645 | 31443 | /* Run the SQL statement prepared by the above block. Store the results |
| @@ -31652,14 +31450,14 @@ | ||
| 31652 | 31450 | sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); |
| 31653 | 31451 | } |
| 31654 | 31452 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 31655 | 31453 | if( nRow>=nAlloc ){ |
| 31656 | 31454 | char **azNew; |
| 31657 | - int n2 = nAlloc*2 + 10; | |
| 31455 | + sqlite3_int64 n2 = 2*(sqlite3_int64)nAlloc + 10; | |
| 31658 | 31456 | azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); |
| 31659 | 31457 | shell_check_oom(azNew); |
| 31660 | - nAlloc = n2; | |
| 31458 | + nAlloc = (int)n2; | |
| 31661 | 31459 | azResult = azNew; |
| 31662 | 31460 | } |
| 31663 | 31461 | azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); |
| 31664 | 31462 | shell_check_oom(azResult[nRow]); |
| 31665 | 31463 | nRow++; |
| @@ -31818,11 +31616,11 @@ | ||
| 31818 | 31616 | { 0x00000020, 1, "CoverIdxScan" }, |
| 31819 | 31617 | { 0x00000040, 1, "OrderByIdxJoin" }, |
| 31820 | 31618 | { 0x00000080, 1, "Transitive" }, |
| 31821 | 31619 | { 0x00000100, 1, "OmitNoopJoin" }, |
| 31822 | 31620 | { 0x00000200, 1, "CountOfView" }, |
| 31823 | - { 0x00000400, 1, "CurosrHints" }, | |
| 31621 | + { 0x00000400, 1, "CursorHints" }, | |
| 31824 | 31622 | { 0x00000800, 1, "Stat4" }, |
| 31825 | 31623 | { 0x00001000, 1, "PushDown" }, |
| 31826 | 31624 | { 0x00002000, 1, "SimplifyJoin" }, |
| 31827 | 31625 | { 0x00004000, 1, "SkipScan" }, |
| 31828 | 31626 | { 0x00008000, 1, "PropagateConst" }, |
| @@ -32365,11 +32163,14 @@ | ||
| 32365 | 32163 | p->nWidth = nArg-1; |
| 32366 | 32164 | p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2); |
| 32367 | 32165 | if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory(); |
| 32368 | 32166 | if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth]; |
| 32369 | 32167 | for(j=1; j<nArg; j++){ |
| 32370 | - p->colWidth[j-1] = (int)integerValue(azArg[j]); | |
| 32168 | + i64 w = integerValue(azArg[j]); | |
| 32169 | + if( w < -30000 ) w = -30000; | |
| 32170 | + if( w > +30000 ) w = +30000; | |
| 32171 | + p->colWidth[j-1] = (int)w; | |
| 32371 | 32172 | } |
| 32372 | 32173 | }else |
| 32373 | 32174 | |
| 32374 | 32175 | { |
| 32375 | 32176 | sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " |
| @@ -32888,76 +32689,95 @@ | ||
| 32888 | 32689 | |
| 32889 | 32690 | return home_dir; |
| 32890 | 32691 | } |
| 32891 | 32692 | |
| 32892 | 32693 | /* |
| 32893 | -** On non-Windows platforms, look for $XDG_CONFIG_HOME. | |
| 32894 | -** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return | |
| 32895 | -** the path to it. If there is no $(XDG_CONFIG_HOME) then | |
| 32896 | -** look for $(HOME)/.config/sqlite3/sqliterc and if found | |
| 32897 | -** return that. If none of these are found, return 0. | |
| 32694 | +** On non-Windows platforms, look for: | |
| 32695 | +** | |
| 32696 | +** - ${zEnvVar}/${zBaseName} | |
| 32697 | +** - ${HOME}/${zSubdir}/${zBaseName} | |
| 32698 | +** | |
| 32699 | +** $zEnvVar is intended to be the name of an XDG_... environment | |
| 32700 | +** variable, e.g. XDG_CONFIG_HOME or XDG_STATE_HOME. If zEnvVar is | |
| 32701 | +** NULL or getenv(zEnvVar) is NULL then fall back to the second | |
| 32702 | +** option. If the selected option is not found in the filesystem, | |
| 32703 | +** return 0. | |
| 32704 | +** | |
| 32705 | +** zSubdir may be NULL or empty, in which case ${HOME}/${zBaseName} | |
| 32706 | +** becomes the fallback. | |
| 32707 | +** | |
| 32708 | +** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir | |
| 32709 | +** will conventionally be ".config" or ".local/state", which, not | |
| 32710 | +** coincidentally, is the typical subdir of the corresponding XDG_... | |
| 32711 | +** var with the XDG var's $HOME prefix. | |
| 32898 | 32712 | ** |
| 32899 | -** The string returned is obtained from sqlite3_malloc() and | |
| 32900 | -** should be freed by the caller. | |
| 32713 | +** The returned string is obtained from sqlite3_malloc() and should be | |
| 32714 | +** sqlite3_free()'d by the caller. | |
| 32901 | 32715 | */ |
| 32902 | -static char *find_xdg_config(void){ | |
| 32716 | +static char *find_xdg_file(const char *zEnvVar, const char *zSubdir, | |
| 32717 | + const char *zBaseName){ | |
| 32903 | 32718 | #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ |
| 32904 | 32719 | || defined(__RTP__) || defined(_WRS_KERNEL) |
| 32905 | 32720 | return 0; |
| 32906 | 32721 | #else |
| 32907 | - char *zConfig = 0; | |
| 32908 | - const char *zXdgHome; | |
| 32909 | - | |
| 32910 | - zXdgHome = getenv("XDG_CONFIG_HOME"); | |
| 32911 | - if( zXdgHome==0 ){ | |
| 32912 | - const char *zHome = getenv("HOME"); | |
| 32913 | - if( zHome==0 ) return 0; | |
| 32914 | - zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome); | |
| 32722 | + char *zConfigFile = 0; | |
| 32723 | + const char *zXdgDir; | |
| 32724 | + | |
| 32725 | + zXdgDir = zEnvVar ? getenv(zEnvVar) : 0; | |
| 32726 | + if( zXdgDir ){ | |
| 32727 | + zConfigFile = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName); | |
| 32915 | 32728 | }else{ |
| 32916 | - zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); | |
| 32917 | - } | |
| 32918 | - shell_check_oom(zConfig); | |
| 32919 | - if( access(zConfig,0)!=0 ){ | |
| 32920 | - sqlite3_free(zConfig); | |
| 32921 | - zConfig = 0; | |
| 32922 | - } | |
| 32923 | - return zConfig; | |
| 32729 | + const char * zHome = find_home_dir(0); | |
| 32730 | + if( zHome==0 ) return 0; | |
| 32731 | + zConfigFile = (zSubdir && *zSubdir) | |
| 32732 | + ? sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName) | |
| 32733 | + : sqlite3_mprintf("%s/%s", zHome, zBaseName); | |
| 32734 | + } | |
| 32735 | + shell_check_oom(zConfigFile); | |
| 32736 | + if( access(zConfigFile,0)!=0 ){ | |
| 32737 | + sqlite3_free(zConfigFile); | |
| 32738 | + zConfigFile = 0; | |
| 32739 | + } | |
| 32740 | + return zConfigFile; | |
| 32924 | 32741 | #endif |
| 32925 | 32742 | } |
| 32926 | 32743 | |
| 32927 | 32744 | /* |
| 32928 | -** Read input from the file given by sqliterc_override. Or if that | |
| 32929 | -** parameter is NULL, take input from the first of find_xdg_config() | |
| 32930 | -** or ~/.sqliterc which is found. | |
| 32745 | +** Read input from the file sqliterc_override. If that parameter is | |
| 32746 | +** NULL, take it from find_xdg_file(), if found, or fall back to | |
| 32747 | +** ~/.sqliterc. | |
| 32931 | 32748 | ** |
| 32932 | -** Returns the number of errors. | |
| 32749 | +** Failure to read the config is only considered a failure if | |
| 32750 | +** sqliterc_override is not NULL, in which case this function may emit | |
| 32751 | +** a warning or, if ::bail_on_error is true, fail fatally if the file | |
| 32752 | +** named by sqliterc_override is not found. | |
| 32933 | 32753 | */ |
| 32934 | 32754 | static void process_sqliterc( |
| 32935 | 32755 | ShellState *p, /* Configuration data */ |
| 32936 | 32756 | const char *sqliterc_override /* Name of config file. NULL to use default */ |
| 32937 | 32757 | ){ |
| 32938 | 32758 | char *home_dir = NULL; |
| 32939 | - const char *sqliterc = sqliterc_override; | |
| 32940 | - char *zBuf = 0; | |
| 32759 | + char *sqliterc = (char*)sqliterc_override; | |
| 32941 | 32760 | FILE *inSaved = p->in; |
| 32942 | 32761 | int savedLineno = p->lineno; |
| 32943 | 32762 | |
| 32944 | 32763 | if( sqliterc == NULL ){ |
| 32945 | - sqliterc = zBuf = find_xdg_config(); | |
| 32764 | + sqliterc = find_xdg_file("XDG_CONFIG_HOME", | |
| 32765 | + ".config", | |
| 32766 | + "sqlite3/sqliterc"); | |
| 32946 | 32767 | } |
| 32947 | 32768 | if( sqliterc == NULL ){ |
| 32948 | 32769 | home_dir = find_home_dir(0); |
| 32949 | 32770 | if( home_dir==0 ){ |
| 32950 | 32771 | eputz("-- warning: cannot find home directory;" |
| 32951 | 32772 | " cannot read ~/.sqliterc\n"); |
| 32952 | 32773 | return; |
| 32953 | 32774 | } |
| 32954 | - zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); | |
| 32955 | - shell_check_oom(zBuf); | |
| 32956 | - sqliterc = zBuf; | |
| 32775 | + sqliterc = sqlite3_mprintf("%s/.sqliterc",home_dir); | |
| 32776 | + shell_check_oom(sqliterc); | |
| 32957 | 32777 | } |
| 32958 | - p->in = sqlite3_fopen(sqliterc,"rb"); | |
| 32778 | + p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0; | |
| 32959 | 32779 | if( p->in ){ |
| 32960 | 32780 | if( stdin_is_interactive ){ |
| 32961 | 32781 | sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); |
| 32962 | 32782 | } |
| 32963 | 32783 | if( process_input(p) && bail_on_error ) exit(1); |
| @@ -32966,11 +32786,13 @@ | ||
| 32966 | 32786 | sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); |
| 32967 | 32787 | if( bail_on_error ) exit(1); |
| 32968 | 32788 | } |
| 32969 | 32789 | p->in = inSaved; |
| 32970 | 32790 | p->lineno = savedLineno; |
| 32971 | - sqlite3_free(zBuf); | |
| 32791 | + if( sqliterc != sqliterc_override ){ | |
| 32792 | + sqlite3_free(sqliterc); | |
| 32793 | + } | |
| 32972 | 32794 | } |
| 32973 | 32795 | |
| 32974 | 32796 | /* |
| 32975 | 32797 | ** Show available command line options |
| 32976 | 32798 | */ |
| @@ -32997,10 +32819,11 @@ | ||
| 32997 | 32819 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
| 32998 | 32820 | " -heap SIZE Size of heap for memsys3 or memsys5\n" |
| 32999 | 32821 | #endif |
| 33000 | 32822 | " -help show this message\n" |
| 33001 | 32823 | " -html set output mode to HTML\n" |
| 32824 | + " -ifexists only open if database already exists\n" | |
| 33002 | 32825 | " -interactive force interactive I/O\n" |
| 33003 | 32826 | " -json set output mode to 'json'\n" |
| 33004 | 32827 | " -line set output mode to 'line'\n" |
| 33005 | 32828 | " -list set output mode to 'list'\n" |
| 33006 | 32829 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| @@ -33341,16 +33164,24 @@ | ||
| 33341 | 33164 | (void)cmdline_option_value(argc, argv, ++i); |
| 33342 | 33165 | #endif |
| 33343 | 33166 | }else if( cli_strcmp(z,"-pagecache")==0 ){ |
| 33344 | 33167 | sqlite3_int64 n, sz; |
| 33345 | 33168 | sz = integerValue(cmdline_option_value(argc,argv,++i)); |
| 33346 | - if( sz>70000 ) sz = 70000; | |
| 33169 | + if( sz>65536 ) sz = 65536; | |
| 33347 | 33170 | if( sz<0 ) sz = 0; |
| 33348 | 33171 | n = integerValue(cmdline_option_value(argc,argv,++i)); |
| 33349 | 33172 | if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){ |
| 33350 | 33173 | n = 0xffffffffffffLL/sz; |
| 33351 | 33174 | } |
| 33175 | + if( sz>0 && (sz & (sz-1))==0 ){ | |
| 33176 | + /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */ | |
| 33177 | + int szHdr = 0; | |
| 33178 | + sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr); | |
| 33179 | + sz += szHdr; | |
| 33180 | + sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate" | |
| 33181 | + " the %d-byte headers\n", (int)sz, szHdr); | |
| 33182 | + } | |
| 33352 | 33183 | verify_uninitialized(); |
| 33353 | 33184 | sqlite3_config(SQLITE_CONFIG_PAGECACHE, |
| 33354 | 33185 | (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); |
| 33355 | 33186 | data.shellFlgs |= SHFLG_Pagecache; |
| 33356 | 33187 | }else if( cli_strcmp(z,"-lookaside")==0 ){ |
| @@ -33359,11 +33190,11 @@ | ||
| 33359 | 33190 | if( sz<0 ) sz = 0; |
| 33360 | 33191 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
| 33361 | 33192 | if( n<0 ) n = 0; |
| 33362 | 33193 | verify_uninitialized(); |
| 33363 | 33194 | sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); |
| 33364 | - if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; | |
| 33195 | + if( (i64)sz*(i64)n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; | |
| 33365 | 33196 | }else if( cli_strcmp(z,"-threadsafe")==0 ){ |
| 33366 | 33197 | int n; |
| 33367 | 33198 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
| 33368 | 33199 | verify_uninitialized(); |
| 33369 | 33200 | switch( n ){ |
| @@ -33401,13 +33232,19 @@ | ||
| 33401 | 33232 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33402 | 33233 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33403 | 33234 | data.szMax = integerValue(argv[++i]); |
| 33404 | 33235 | #endif |
| 33405 | 33236 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33406 | - data.openMode = SHELL_OPEN_READONLY; | |
| 33237 | + data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | |
| 33238 | + data.openFlags |= SQLITE_OPEN_READONLY; | |
| 33407 | 33239 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33408 | - data.openFlags = SQLITE_OPEN_NOFOLLOW; | |
| 33240 | + data.openFlags |= SQLITE_OPEN_NOFOLLOW; | |
| 33241 | + }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ | |
| 33242 | + data.openFlags |= SQLITE_OPEN_EXCLUSIVE; | |
| 33243 | + }else if( cli_strcmp(z,"-ifexists")==0 ){ | |
| 33244 | + data.openFlags &= ~(SQLITE_OPEN_CREATE); | |
| 33245 | + if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; | |
| 33409 | 33246 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
| 33410 | 33247 | }else if( cli_strncmp(z, "-A",2)==0 ){ |
| 33411 | 33248 | /* All remaining command-line arguments are passed to the ".archive" |
| 33412 | 33249 | ** command, so ignore them */ |
| 33413 | 33250 | break; |
| @@ -33557,13 +33394,19 @@ | ||
| 33557 | 33394 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33558 | 33395 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33559 | 33396 | data.szMax = integerValue(argv[++i]); |
| 33560 | 33397 | #endif |
| 33561 | 33398 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33562 | - data.openMode = SHELL_OPEN_READONLY; | |
| 33399 | + data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | |
| 33400 | + data.openFlags |= SQLITE_OPEN_READONLY; | |
| 33563 | 33401 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33564 | 33402 | data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 33403 | + }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ | |
| 33404 | + data.openFlags |= SQLITE_OPEN_EXCLUSIVE; | |
| 33405 | + }else if( cli_strcmp(z,"-ifexists")==0 ){ | |
| 33406 | + data.openFlags &= ~(SQLITE_OPEN_CREATE); | |
| 33407 | + if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; | |
| 33565 | 33408 | }else if( cli_strcmp(z,"-ascii")==0 ){ |
| 33566 | 33409 | data.mode = MODE_Ascii; |
| 33567 | 33410 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit); |
| 33568 | 33411 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record); |
| 33569 | 33412 | }else if( cli_strcmp(z,"-tabs")==0 ){ |
| @@ -33734,11 +33577,10 @@ | ||
| 33734 | 33577 | /* Run commands received from standard input |
| 33735 | 33578 | */ |
| 33736 | 33579 | if( stdin_is_interactive ){ |
| 33737 | 33580 | char *zHome; |
| 33738 | 33581 | char *zHistory; |
| 33739 | - int nHistory; | |
| 33740 | 33582 | sqlite3_fprintf(stdout, |
| 33741 | 33583 | "SQLite version %s %.19s\n" /*extra-version-info*/ |
| 33742 | 33584 | "Enter \".help\" for usage hints.\n", |
| 33743 | 33585 | sqlite3_libversion(), sqlite3_sourceid()); |
| 33744 | 33586 | if( warnInmemoryDb ){ |
| @@ -33747,15 +33589,19 @@ | ||
| 33747 | 33589 | sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a" |
| 33748 | 33590 | " persistent database.\n"); |
| 33749 | 33591 | } |
| 33750 | 33592 | zHistory = getenv("SQLITE_HISTORY"); |
| 33751 | 33593 | if( zHistory ){ |
| 33752 | - zHistory = strdup(zHistory); | |
| 33753 | - }else if( (zHome = find_home_dir(0))!=0 ){ | |
| 33754 | - nHistory = strlen30(zHome) + 20; | |
| 33755 | - if( (zHistory = malloc(nHistory))!=0 ){ | |
| 33756 | - sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); | |
| 33594 | + zHistory = sqlite3_mprintf("%s", zHistory); | |
| 33595 | + shell_check_oom(zHistory); | |
| 33596 | + }else{ | |
| 33597 | + zHistory = find_xdg_file("XDG_STATE_HOME", | |
| 33598 | + ".local/state", | |
| 33599 | + "sqlite_history"); | |
| 33600 | + if( 0==zHistory && (zHome = find_home_dir(0))!=0 ){ | |
| 33601 | + zHistory = sqlite3_mprintf("%s/.sqlite_history", zHome); | |
| 33602 | + shell_check_oom(zHistory); | |
| 33757 | 33603 | } |
| 33758 | 33604 | } |
| 33759 | 33605 | if( zHistory ){ shell_read_history(zHistory); } |
| 33760 | 33606 | #if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) |
| 33761 | 33607 | rl_attempted_completion_function = readline_completion; |
| @@ -33767,21 +33613,21 @@ | ||
| 33767 | 33613 | data.in = 0; |
| 33768 | 33614 | rc = process_input(&data); |
| 33769 | 33615 | if( zHistory ){ |
| 33770 | 33616 | shell_stifle_history(2000); |
| 33771 | 33617 | shell_write_history(zHistory); |
| 33772 | - free(zHistory); | |
| 33618 | + sqlite3_free(zHistory); | |
| 33773 | 33619 | } |
| 33774 | 33620 | }else{ |
| 33775 | 33621 | data.in = stdin; |
| 33776 | 33622 | rc = process_input(&data); |
| 33777 | 33623 | } |
| 33778 | 33624 | } |
| 33779 | 33625 | #ifndef SQLITE_SHELL_FIDDLE |
| 33780 | 33626 | /* In WASM mode we have to leave the db state in place so that |
| 33781 | 33627 | ** client code can "push" SQL into it after this call returns. */ |
| 33782 | -#ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 33628 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 33783 | 33629 | if( data.expert.pExpert ){ |
| 33784 | 33630 | expertFinish(&data, 1, 0); |
| 33785 | 33631 | } |
| 33786 | 33632 | #endif |
| 33787 | 33633 | shell_main_exit: |
| 33788 | 33634 |
| --- extsrc/shell.c | |
| +++ extsrc/shell.c | |
| @@ -122,10 +122,13 @@ | |
| 122 | typedef sqlite3_int64 i64; |
| 123 | typedef sqlite3_uint64 u64; |
| 124 | typedef unsigned char u8; |
| 125 | #include <ctype.h> |
| 126 | #include <stdarg.h> |
| 127 | |
| 128 | #if !defined(_WIN32) && !defined(WIN32) |
| 129 | # include <signal.h> |
| 130 | # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI) |
| 131 | # include <pwd.h> |
| @@ -646,12 +649,23 @@ | |
| 646 | if( a==0 ) a = ""; |
| 647 | if( b==0 ) b = ""; |
| 648 | return strncmp(a,b,n); |
| 649 | } |
| 650 | |
| 651 | /* Return the current wall-clock time */ |
| 652 | static sqlite3_int64 timeOfDay(void){ |
| 653 | static sqlite3_vfs *clockVfs = 0; |
| 654 | sqlite3_int64 t; |
| 655 | if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); |
| 656 | if( clockVfs==0 ) return 0; /* Never actually happens */ |
| 657 | if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ |
| @@ -659,11 +673,16 @@ | |
| 659 | }else{ |
| 660 | double r; |
| 661 | clockVfs->xCurrentTime(clockVfs, &r); |
| 662 | t = (sqlite3_int64)(r*86400000.0); |
| 663 | } |
| 664 | return t; |
| 665 | } |
| 666 | |
| 667 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) |
| 668 | #include <sys/time.h> |
| 669 | #include <sys/resource.h> |
| @@ -704,12 +723,12 @@ | |
| 704 | static void endTimer(FILE *out){ |
| 705 | if( enableTimer ){ |
| 706 | sqlite3_int64 iEnd = timeOfDay(); |
| 707 | struct rusage sEnd; |
| 708 | getrusage(RUSAGE_SELF, &sEnd); |
| 709 | sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", |
| 710 | (iEnd - iBegin)*0.001, |
| 711 | timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |
| 712 | timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
| 713 | } |
| 714 | } |
| 715 | |
| @@ -783,14 +802,23 @@ | |
| 783 | static void endTimer(FILE *out){ |
| 784 | if( enableTimer && getProcessTimesAddr){ |
| 785 | FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
| 786 | sqlite3_int64 ftWallEnd = timeOfDay(); |
| 787 | getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); |
| 788 | sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", |
| 789 | (ftWallEnd - ftWallBegin)*0.001, |
| 790 | timeDiff(&ftUserBegin, &ftUserEnd), |
| 791 | timeDiff(&ftKernelBegin, &ftKernelEnd)); |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | #define BEGIN_TIMER beginTimer() |
| 796 | #define END_TIMER(X) endTimer(X) |
| @@ -1126,11 +1154,11 @@ | |
| 1126 | } |
| 1127 | if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 |
| 1128 | && (z[3] & 0xc0)==0x80 |
| 1129 | ){ |
| 1130 | *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 |
| 1131 | | (z[4] & 0x3f); |
| 1132 | return 4; |
| 1133 | } |
| 1134 | *pU = 0; |
| 1135 | return 1; |
| 1136 | } |
| @@ -1189,18 +1217,28 @@ | |
| 1189 | ** since with %*.*s the width is measured in bytes, not characters. |
| 1190 | ** |
| 1191 | ** Take into account zero-width and double-width Unicode characters. |
| 1192 | ** In other words, a zero-width character does not count toward the |
| 1193 | ** the w limit. A double-width character counts as two. |
| 1194 | */ |
| 1195 | static void utf8_width_print(FILE *out, int w, const char *zUtf){ |
| 1196 | const unsigned char *a = (const unsigned char*)zUtf; |
| 1197 | unsigned char c; |
| 1198 | int i = 0; |
| 1199 | int n = 0; |
| 1200 | int k; |
| 1201 | int aw = w<0 ? -w : w; |
| 1202 | if( zUtf==0 ) zUtf = ""; |
| 1203 | while( (c = a[i])!=0 ){ |
| 1204 | if( (c&0xc0)==0xc0 ){ |
| 1205 | int u; |
| 1206 | int len = decodeUtf8(a+i, &u); |
| @@ -1323,11 +1361,11 @@ | |
| 1323 | |
| 1324 | /* |
| 1325 | ** This routine reads a line of text from FILE in, stores |
| 1326 | ** the text in memory obtained from malloc() and returns a pointer |
| 1327 | ** to the text. NULL is returned at end of file, or if malloc() |
| 1328 | ** fails. |
| 1329 | ** |
| 1330 | ** If zLine is not NULL then it is a malloced buffer returned from |
| 1331 | ** a previous call to this routine that may be reused. |
| 1332 | */ |
| 1333 | static char *local_getline(char *zLine, FILE *in){ |
| @@ -1334,10 +1372,14 @@ | |
| 1334 | int nLine = zLine==0 ? 0 : 100; |
| 1335 | int n = 0; |
| 1336 | |
| 1337 | while( 1 ){ |
| 1338 | if( n+100>nLine ){ |
| 1339 | nLine = nLine*2 + 100; |
| 1340 | zLine = realloc(zLine, nLine); |
| 1341 | shell_check_oom(zLine); |
| 1342 | } |
| 1343 | if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ |
| @@ -1417,14 +1459,18 @@ | |
| 1417 | return -1; |
| 1418 | } |
| 1419 | |
| 1420 | /* |
| 1421 | ** Interpret zArg as an integer value, possibly with suffixes. |
| 1422 | */ |
| 1423 | static sqlite3_int64 integerValue(const char *zArg){ |
| 1424 | sqlite3_int64 v = 0; |
| 1425 | static const struct { char *zSuffix; int iMult; } aMult[] = { |
| 1426 | { "KiB", 1024 }, |
| 1427 | { "MiB", 1024*1024 }, |
| 1428 | { "GiB", 1024*1024*1024 }, |
| 1429 | { "KB", 1000 }, |
| 1430 | { "MB", 1000000 }, |
| @@ -1443,46 +1489,54 @@ | |
| 1443 | } |
| 1444 | if( zArg[0]=='0' && zArg[1]=='x' ){ |
| 1445 | int x; |
| 1446 | zArg += 2; |
| 1447 | while( (x = hexDigitValue(zArg[0]))>=0 ){ |
| 1448 | v = (v<<4) + x; |
| 1449 | zArg++; |
| 1450 | } |
| 1451 | }else{ |
| 1452 | while( IsDigit(zArg[0]) ){ |
| 1453 | v = v*10 + zArg[0] - '0'; |
| 1454 | zArg++; |
| 1455 | } |
| 1456 | } |
| 1457 | for(i=0; i<ArraySize(aMult); i++){ |
| 1458 | if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ |
| 1459 | v *= aMult[i].iMult; |
| 1460 | break; |
| 1461 | } |
| 1462 | } |
| 1463 | return isNeg? -v : v; |
| 1464 | } |
| 1465 | |
| 1466 | /* |
| 1467 | ** A variable length string to which one can append text. |
| 1468 | */ |
| 1469 | typedef struct ShellText ShellText; |
| 1470 | struct ShellText { |
| 1471 | char *z; |
| 1472 | int n; |
| 1473 | int nAlloc; |
| 1474 | }; |
| 1475 | |
| 1476 | /* |
| 1477 | ** Initialize and destroy a ShellText object |
| 1478 | */ |
| 1479 | static void initText(ShellText *p){ |
| 1480 | memset(p, 0, sizeof(*p)); |
| 1481 | } |
| 1482 | static void freeText(ShellText *p){ |
| 1483 | free(p->z); |
| 1484 | initText(p); |
| 1485 | } |
| 1486 | |
| 1487 | /* zIn is either a pointer to a NULL-terminated string in memory obtained |
| 1488 | ** from malloc(), or a NULL pointer. The string pointed to by zAppend is |
| @@ -1503,30 +1557,30 @@ | |
| 1503 | for(i=0; i<nAppend; i++){ |
| 1504 | if( zAppend[i]==quote ) len++; |
| 1505 | } |
| 1506 | } |
| 1507 | |
| 1508 | if( p->z==0 || p->n+len>=p->nAlloc ){ |
| 1509 | p->nAlloc = p->nAlloc*2 + len + 20; |
| 1510 | p->z = realloc(p->z, p->nAlloc); |
| 1511 | shell_check_oom(p->z); |
| 1512 | } |
| 1513 | |
| 1514 | if( quote ){ |
| 1515 | char *zCsr = p->z+p->n; |
| 1516 | *zCsr++ = quote; |
| 1517 | for(i=0; i<nAppend; i++){ |
| 1518 | *zCsr++ = zAppend[i]; |
| 1519 | if( zAppend[i]==quote ) *zCsr++ = quote; |
| 1520 | } |
| 1521 | *zCsr++ = quote; |
| 1522 | p->n = (int)(zCsr - p->z); |
| 1523 | *zCsr = '\0'; |
| 1524 | }else{ |
| 1525 | memcpy(p->z+p->n, zAppend, nAppend); |
| 1526 | p->n += nAppend; |
| 1527 | p->z[p->n] = '\0'; |
| 1528 | } |
| 1529 | } |
| 1530 | |
| 1531 | /* |
| 1532 | ** Attempt to determine if identifier zName needs to be quoted, either |
| @@ -1547,10 +1601,13 @@ | |
| 1547 | } |
| 1548 | |
| 1549 | /* |
| 1550 | ** Construct a fake object name and column list to describe the structure |
| 1551 | ** of the view, virtual table, or table valued function zSchema.zName. |
| 1552 | */ |
| 1553 | static char *shellFakeSchema( |
| 1554 | sqlite3 *db, /* The database connection containing the vtab */ |
| 1555 | const char *zSchema, /* Schema of the database holding the vtab */ |
| 1556 | const char *zName /* The name of the virtual table */ |
| @@ -1587,13 +1644,13 @@ | |
| 1587 | } |
| 1588 | appendText(&s, ")", 0); |
| 1589 | sqlite3_finalize(pStmt); |
| 1590 | if( nRow==0 ){ |
| 1591 | freeText(&s); |
| 1592 | s.z = 0; |
| 1593 | } |
| 1594 | return s.z; |
| 1595 | } |
| 1596 | |
| 1597 | /* |
| 1598 | ** SQL function: strtod(X) |
| 1599 | ** |
| @@ -1692,11 +1749,11 @@ | |
| 1692 | if( z==0 ){ |
| 1693 | z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake); |
| 1694 | }else{ |
| 1695 | z = sqlite3_mprintf("%z\n/* %s */", z, zFake); |
| 1696 | } |
| 1697 | free(zFake); |
| 1698 | } |
| 1699 | if( z ){ |
| 1700 | sqlite3_result_text(pCtx, z, -1, sqlite3_free); |
| 1701 | return; |
| 1702 | } |
| @@ -3667,11 +3724,12 @@ | |
| 3667 | iExp -= p->nFrac; |
| 3668 | p->nFrac = 0; |
| 3669 | } |
| 3670 | } |
| 3671 | if( iExp>0 ){ |
| 3672 | p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); |
| 3673 | if( p->a==0 ) goto new_from_text_failed; |
| 3674 | memset(p->a+p->nDigit, 0, iExp); |
| 3675 | p->nDigit += iExp; |
| 3676 | } |
| 3677 | }else if( iExp<0 ){ |
| @@ -3686,18 +3744,23 @@ | |
| 3686 | iExp -= nExtra; |
| 3687 | p->nFrac = p->nDigit - 1; |
| 3688 | } |
| 3689 | } |
| 3690 | if( iExp>0 ){ |
| 3691 | p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); |
| 3692 | if( p->a==0 ) goto new_from_text_failed; |
| 3693 | memmove(p->a+iExp, p->a, p->nDigit); |
| 3694 | memset(p->a, 0, iExp); |
| 3695 | p->nDigit += iExp; |
| 3696 | p->nFrac += iExp; |
| 3697 | } |
| 3698 | } |
| 3699 | return p; |
| 3700 | |
| 3701 | new_from_text_failed: |
| 3702 | if( p ){ |
| 3703 | if( p->a ) sqlite3_free(p->a); |
| @@ -3786,11 +3849,11 @@ | |
| 3786 | } |
| 3787 | if( p->isNull ){ |
| 3788 | sqlite3_result_null(pCtx); |
| 3789 | return; |
| 3790 | } |
| 3791 | z = sqlite3_malloc( p->nDigit+4 ); |
| 3792 | if( z==0 ){ |
| 3793 | sqlite3_result_error_nomem(pCtx); |
| 3794 | return; |
| 3795 | } |
| 3796 | i = 0; |
| @@ -3851,11 +3914,11 @@ | |
| 3851 | } |
| 3852 | for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){} |
| 3853 | for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){} |
| 3854 | nFrac = p->nFrac + (nDigit - p->nDigit); |
| 3855 | nDigit -= nZero; |
| 3856 | z = sqlite3_malloc( nDigit+20 ); |
| 3857 | if( z==0 ){ |
| 3858 | sqlite3_result_error_nomem(pCtx); |
| 3859 | return; |
| 3860 | } |
| 3861 | if( nDigit==0 ){ |
| @@ -3896,17 +3959,25 @@ | |
| 3896 | ** pA!=0 |
| 3897 | ** pA->isNull==0 |
| 3898 | ** pB!=0 |
| 3899 | ** pB->isNull==0 |
| 3900 | */ |
| 3901 | static int decimal_cmp(const Decimal *pA, const Decimal *pB){ |
| 3902 | int nASig, nBSig, rc, n; |
| 3903 | if( pA->sign!=pB->sign ){ |
| 3904 | return pA->sign ? -1 : +1; |
| 3905 | } |
| 3906 | if( pA->sign ){ |
| 3907 | const Decimal *pTemp = pA; |
| 3908 | pA = pB; |
| 3909 | pB = pTemp; |
| 3910 | } |
| 3911 | nASig = pA->nDigit - pA->nFrac; |
| 3912 | nBSig = pB->nDigit - pB->nFrac; |
| @@ -4064,11 +4135,12 @@ | |
| 4064 | if( pA==0 || pA->oom || pA->isNull |
| 4065 | || pB==0 || pB->oom || pB->isNull |
| 4066 | ){ |
| 4067 | goto mul_end; |
| 4068 | } |
| 4069 | acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 ); |
| 4070 | if( acc==0 ){ |
| 4071 | pA->oom = 1; |
| 4072 | goto mul_end; |
| 4073 | } |
| 4074 | memset(acc, 0, pA->nDigit + pB->nDigit + 2); |
| @@ -4151,11 +4223,11 @@ | |
| 4151 | r = -r; |
| 4152 | }else{ |
| 4153 | isNeg = 0; |
| 4154 | } |
| 4155 | memcpy(&a,&r,sizeof(a)); |
| 4156 | if( a==0 ){ |
| 4157 | e = 0; |
| 4158 | m = 0; |
| 4159 | }else{ |
| 4160 | e = a>>52; |
| 4161 | m = a & ((((sqlite3_int64)1)<<52)-1); |
| @@ -4426,516 +4498,10 @@ | |
| 4426 | } |
| 4427 | return rc; |
| 4428 | } |
| 4429 | |
| 4430 | /************************* End ../ext/misc/decimal.c ********************/ |
| 4431 | /************************* Begin ../ext/misc/percentile.c ******************/ |
| 4432 | /* |
| 4433 | ** 2013-05-28 |
| 4434 | ** |
| 4435 | ** The author disclaims copyright to this source code. In place of |
| 4436 | ** a legal notice, here is a blessing: |
| 4437 | ** |
| 4438 | ** May you do good and not evil. |
| 4439 | ** May you find forgiveness for yourself and forgive others. |
| 4440 | ** May you share freely, never taking more than you give. |
| 4441 | ** |
| 4442 | ****************************************************************************** |
| 4443 | ** |
| 4444 | ** This file contains code to implement the percentile(Y,P) SQL function |
| 4445 | ** and similar as described below: |
| 4446 | ** |
| 4447 | ** (1) The percentile(Y,P) function is an aggregate function taking |
| 4448 | ** exactly two arguments. |
| 4449 | ** |
| 4450 | ** (2) If the P argument to percentile(Y,P) is not the same for every |
| 4451 | ** row in the aggregate then an error is thrown. The word "same" |
| 4452 | ** in the previous sentence means that the value differ by less |
| 4453 | ** than 0.001. |
| 4454 | ** |
| 4455 | ** (3) If the P argument to percentile(Y,P) evaluates to anything other |
| 4456 | ** than a number in the range of 0.0 to 100.0 inclusive then an |
| 4457 | ** error is thrown. |
| 4458 | ** |
| 4459 | ** (4) If any Y argument to percentile(Y,P) evaluates to a value that |
| 4460 | ** is not NULL and is not numeric then an error is thrown. |
| 4461 | ** |
| 4462 | ** (5) If any Y argument to percentile(Y,P) evaluates to plus or minus |
| 4463 | ** infinity then an error is thrown. (SQLite always interprets NaN |
| 4464 | ** values as NULL.) |
| 4465 | ** |
| 4466 | ** (6) Both Y and P in percentile(Y,P) can be arbitrary expressions, |
| 4467 | ** including CASE WHEN expressions. |
| 4468 | ** |
| 4469 | ** (7) The percentile(Y,P) aggregate is able to handle inputs of at least |
| 4470 | ** one million (1,000,000) rows. |
| 4471 | ** |
| 4472 | ** (8) If there are no non-NULL values for Y, then percentile(Y,P) |
| 4473 | ** returns NULL. |
| 4474 | ** |
| 4475 | ** (9) If there is exactly one non-NULL value for Y, the percentile(Y,P) |
| 4476 | ** returns the one Y value. |
| 4477 | ** |
| 4478 | ** (10) If there N non-NULL values of Y where N is two or more and |
| 4479 | ** the Y values are ordered from least to greatest and a graph is |
| 4480 | ** drawn from 0 to N-1 such that the height of the graph at J is |
| 4481 | ** the J-th Y value and such that straight lines are drawn between |
| 4482 | ** adjacent Y values, then the percentile(Y,P) function returns |
| 4483 | ** the height of the graph at P*(N-1)/100. |
| 4484 | ** |
| 4485 | ** (11) The percentile(Y,P) function always returns either a floating |
| 4486 | ** point number or NULL. |
| 4487 | ** |
| 4488 | ** (12) The percentile(Y,P) is implemented as a single C99 source-code |
| 4489 | ** file that compiles into a shared-library or DLL that can be loaded |
| 4490 | ** into SQLite using the sqlite3_load_extension() interface. |
| 4491 | ** |
| 4492 | ** (13) A separate median(Y) function is the equivalent percentile(Y,50). |
| 4493 | ** |
| 4494 | ** (14) A separate percentile_cont(Y,P) function is equivalent to |
| 4495 | ** percentile(Y,P/100.0). In other words, the fraction value in |
| 4496 | ** the second argument is in the range of 0 to 1 instead of 0 to 100. |
| 4497 | ** |
| 4498 | ** (15) A separate percentile_disc(Y,P) function is like |
| 4499 | ** percentile_cont(Y,P) except that instead of returning the weighted |
| 4500 | ** average of the nearest two input values, it returns the next lower |
| 4501 | ** value. So the percentile_disc(Y,P) will always return a value |
| 4502 | ** that was one of the inputs. |
| 4503 | ** |
| 4504 | ** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and |
| 4505 | ** percentile_disc(Y,P) can be used as window functions. |
| 4506 | ** |
| 4507 | ** Differences from standard SQL: |
| 4508 | ** |
| 4509 | ** * The percentile_cont(X,P) function is equivalent to the following in |
| 4510 | ** standard SQL: |
| 4511 | ** |
| 4512 | ** (percentile_cont(P) WITHIN GROUP (ORDER BY X)) |
| 4513 | ** |
| 4514 | ** The SQLite syntax is much more compact. The standard SQL syntax |
| 4515 | ** is also supported if SQLite is compiled with the |
| 4516 | ** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option. |
| 4517 | ** |
| 4518 | ** * No median(X) function exists in the SQL standard. App developers |
| 4519 | ** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)". |
| 4520 | ** |
| 4521 | ** * No percentile(Y,P) function exists in the SQL standard. Instead of |
| 4522 | ** percential(Y,P), developers must write this: |
| 4523 | ** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that |
| 4524 | ** the fraction parameter to percentile() goes from 0 to 100 whereas |
| 4525 | ** the fraction parameter in SQL standard percentile_cont() goes from |
| 4526 | ** 0 to 1. |
| 4527 | ** |
| 4528 | ** Implementation notes as of 2024-08-31: |
| 4529 | ** |
| 4530 | ** * The regular aggregate-function versions of these routines work |
| 4531 | ** by accumulating all values in an array of doubles, then sorting |
| 4532 | ** that array using quicksort before computing the answer. Thus |
| 4533 | ** the runtime is O(NlogN) where N is the number of rows of input. |
| 4534 | ** |
| 4535 | ** * For the window-function versions of these routines, the array of |
| 4536 | ** inputs is sorted as soon as the first value is computed. Thereafter, |
| 4537 | ** the array is kept in sorted order using an insert-sort. This |
| 4538 | ** results in O(N*K) performance where K is the size of the window. |
| 4539 | ** One can imagine alternative implementations that give O(N*logN*logK) |
| 4540 | ** performance, but they require more complex logic and data structures. |
| 4541 | ** The developers have elected to keep the asymptotically slower |
| 4542 | ** algorithm for now, for simplicity, under the theory that window |
| 4543 | ** functions are seldom used and when they are, the window size K is |
| 4544 | ** often small. The developers might revisit that decision later, |
| 4545 | ** should the need arise. |
| 4546 | */ |
| 4547 | #if defined(SQLITE3_H) |
| 4548 | /* no-op */ |
| 4549 | #elif defined(SQLITE_STATIC_PERCENTILE) |
| 4550 | /* # include "sqlite3.h" */ |
| 4551 | #else |
| 4552 | /* # include "sqlite3ext.h" */ |
| 4553 | SQLITE_EXTENSION_INIT1 |
| 4554 | #endif |
| 4555 | #include <assert.h> |
| 4556 | #include <string.h> |
| 4557 | #include <stdlib.h> |
| 4558 | |
| 4559 | /* The following object is the group context for a single percentile() |
| 4560 | ** aggregate. Remember all input Y values until the very end. |
| 4561 | ** Those values are accumulated in the Percentile.a[] array. |
| 4562 | */ |
| 4563 | typedef struct Percentile Percentile; |
| 4564 | struct Percentile { |
| 4565 | unsigned nAlloc; /* Number of slots allocated for a[] */ |
| 4566 | unsigned nUsed; /* Number of slots actually used in a[] */ |
| 4567 | char bSorted; /* True if a[] is already in sorted order */ |
| 4568 | char bKeepSorted; /* True if advantageous to keep a[] sorted */ |
| 4569 | char bPctValid; /* True if rPct is valid */ |
| 4570 | double rPct; /* Fraction. 0.0 to 1.0 */ |
| 4571 | double *a; /* Array of Y values */ |
| 4572 | }; |
| 4573 | |
| 4574 | /* Details of each function in the percentile family */ |
| 4575 | typedef struct PercentileFunc PercentileFunc; |
| 4576 | struct PercentileFunc { |
| 4577 | const char *zName; /* Function name */ |
| 4578 | char nArg; /* Number of arguments */ |
| 4579 | char mxFrac; /* Maximum value of the "fraction" input */ |
| 4580 | char bDiscrete; /* True for percentile_disc() */ |
| 4581 | }; |
| 4582 | static const PercentileFunc aPercentFunc[] = { |
| 4583 | { "median", 1, 1, 0 }, |
| 4584 | { "percentile", 2, 100, 0 }, |
| 4585 | { "percentile_cont", 2, 1, 0 }, |
| 4586 | { "percentile_disc", 2, 1, 1 }, |
| 4587 | }; |
| 4588 | |
| 4589 | /* |
| 4590 | ** Return TRUE if the input floating-point number is an infinity. |
| 4591 | */ |
| 4592 | static int percentIsInfinity(double r){ |
| 4593 | sqlite3_uint64 u; |
| 4594 | assert( sizeof(u)==sizeof(r) ); |
| 4595 | memcpy(&u, &r, sizeof(u)); |
| 4596 | return ((u>>52)&0x7ff)==0x7ff; |
| 4597 | } |
| 4598 | |
| 4599 | /* |
| 4600 | ** Return TRUE if two doubles differ by 0.001 or less. |
| 4601 | */ |
| 4602 | static int percentSameValue(double a, double b){ |
| 4603 | a -= b; |
| 4604 | return a>=-0.001 && a<=0.001; |
| 4605 | } |
| 4606 | |
| 4607 | /* |
| 4608 | ** Search p (which must have p->bSorted) looking for an entry with |
| 4609 | ** value y. Return the index of that entry. |
| 4610 | ** |
| 4611 | ** If bExact is true, return -1 if the entry is not found. |
| 4612 | ** |
| 4613 | ** If bExact is false, return the index at which a new entry with |
| 4614 | ** value y should be insert in order to keep the values in sorted |
| 4615 | ** order. The smallest return value in this case will be 0, and |
| 4616 | ** the largest return value will be p->nUsed. |
| 4617 | */ |
| 4618 | static int percentBinarySearch(Percentile *p, double y, int bExact){ |
| 4619 | int iFirst = 0; /* First element of search range */ |
| 4620 | int iLast = p->nUsed - 1; /* Last element of search range */ |
| 4621 | while( iLast>=iFirst ){ |
| 4622 | int iMid = (iFirst+iLast)/2; |
| 4623 | double x = p->a[iMid]; |
| 4624 | if( x<y ){ |
| 4625 | iFirst = iMid + 1; |
| 4626 | }else if( x>y ){ |
| 4627 | iLast = iMid - 1; |
| 4628 | }else{ |
| 4629 | return iMid; |
| 4630 | } |
| 4631 | } |
| 4632 | if( bExact ) return -1; |
| 4633 | return iFirst; |
| 4634 | } |
| 4635 | |
| 4636 | /* |
| 4637 | ** Generate an error for a percentile function. |
| 4638 | ** |
| 4639 | ** The error format string must have exactly one occurrence of "%%s()" |
| 4640 | ** (with two '%' characters). That substring will be replaced by the name |
| 4641 | ** of the function. |
| 4642 | */ |
| 4643 | static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ |
| 4644 | PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); |
| 4645 | char *zMsg1; |
| 4646 | char *zMsg2; |
| 4647 | va_list ap; |
| 4648 | |
| 4649 | va_start(ap, zFormat); |
| 4650 | zMsg1 = sqlite3_vmprintf(zFormat, ap); |
| 4651 | va_end(ap); |
| 4652 | zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0; |
| 4653 | sqlite3_result_error(pCtx, zMsg2, -1); |
| 4654 | sqlite3_free(zMsg1); |
| 4655 | sqlite3_free(zMsg2); |
| 4656 | } |
| 4657 | |
| 4658 | /* |
| 4659 | ** The "step" function for percentile(Y,P) is called once for each |
| 4660 | ** input row. |
| 4661 | */ |
| 4662 | static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ |
| 4663 | Percentile *p; |
| 4664 | double rPct; |
| 4665 | int eType; |
| 4666 | double y; |
| 4667 | assert( argc==2 || argc==1 ); |
| 4668 | |
| 4669 | if( argc==1 ){ |
| 4670 | /* Requirement 13: median(Y) is the same as percentile(Y,50). */ |
| 4671 | rPct = 0.5; |
| 4672 | }else{ |
| 4673 | /* Requirement 3: P must be a number between 0 and 100 */ |
| 4674 | PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); |
| 4675 | eType = sqlite3_value_numeric_type(argv[1]); |
| 4676 | rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac; |
| 4677 | if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) |
| 4678 | || rPct<0.0 || rPct>1.0 |
| 4679 | ){ |
| 4680 | percentError(pCtx, "the fraction argument to %%s()" |
| 4681 | " is not between 0.0 and %.1f", |
| 4682 | (double)pFunc->mxFrac); |
| 4683 | return; |
| 4684 | } |
| 4685 | } |
| 4686 | |
| 4687 | /* Allocate the session context. */ |
| 4688 | p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 4689 | if( p==0 ) return; |
| 4690 | |
| 4691 | /* Remember the P value. Throw an error if the P value is different |
| 4692 | ** from any prior row, per Requirement (2). */ |
| 4693 | if( !p->bPctValid ){ |
| 4694 | p->rPct = rPct; |
| 4695 | p->bPctValid = 1; |
| 4696 | }else if( !percentSameValue(p->rPct,rPct) ){ |
| 4697 | percentError(pCtx, "the fraction argument to %%s()" |
| 4698 | " is not the same for all input rows"); |
| 4699 | return; |
| 4700 | } |
| 4701 | |
| 4702 | /* Ignore rows for which Y is NULL */ |
| 4703 | eType = sqlite3_value_type(argv[0]); |
| 4704 | if( eType==SQLITE_NULL ) return; |
| 4705 | |
| 4706 | /* If not NULL, then Y must be numeric. Otherwise throw an error. |
| 4707 | ** Requirement 4 */ |
| 4708 | if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ |
| 4709 | percentError(pCtx, "input to %%s() is not numeric"); |
| 4710 | return; |
| 4711 | } |
| 4712 | |
| 4713 | /* Throw an error if the Y value is infinity or NaN */ |
| 4714 | y = sqlite3_value_double(argv[0]); |
| 4715 | if( percentIsInfinity(y) ){ |
| 4716 | percentError(pCtx, "Inf input to %%s()"); |
| 4717 | return; |
| 4718 | } |
| 4719 | |
| 4720 | /* Allocate and store the Y */ |
| 4721 | if( p->nUsed>=p->nAlloc ){ |
| 4722 | unsigned n = p->nAlloc*2 + 250; |
| 4723 | double *a = sqlite3_realloc64(p->a, sizeof(double)*n); |
| 4724 | if( a==0 ){ |
| 4725 | sqlite3_free(p->a); |
| 4726 | memset(p, 0, sizeof(*p)); |
| 4727 | sqlite3_result_error_nomem(pCtx); |
| 4728 | return; |
| 4729 | } |
| 4730 | p->nAlloc = n; |
| 4731 | p->a = a; |
| 4732 | } |
| 4733 | if( p->nUsed==0 ){ |
| 4734 | p->a[p->nUsed++] = y; |
| 4735 | p->bSorted = 1; |
| 4736 | }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){ |
| 4737 | p->a[p->nUsed++] = y; |
| 4738 | }else if( p->bKeepSorted ){ |
| 4739 | int i; |
| 4740 | i = percentBinarySearch(p, y, 0); |
| 4741 | if( i<(int)p->nUsed ){ |
| 4742 | memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0])); |
| 4743 | } |
| 4744 | p->a[i] = y; |
| 4745 | p->nUsed++; |
| 4746 | }else{ |
| 4747 | p->a[p->nUsed++] = y; |
| 4748 | p->bSorted = 0; |
| 4749 | } |
| 4750 | } |
| 4751 | |
| 4752 | /* |
| 4753 | ** Interchange two doubles. |
| 4754 | */ |
| 4755 | #define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} |
| 4756 | |
| 4757 | /* |
| 4758 | ** Sort an array of doubles. |
| 4759 | ** |
| 4760 | ** Algorithm: quicksort |
| 4761 | ** |
| 4762 | ** This is implemented separately rather than using the qsort() routine |
| 4763 | ** from the standard library because: |
| 4764 | ** |
| 4765 | ** (1) To avoid a dependency on qsort() |
| 4766 | ** (2) To avoid the function call to the comparison routine for each |
| 4767 | ** comparison. |
| 4768 | */ |
| 4769 | static void percentSort(double *a, unsigned int n){ |
| 4770 | int iLt; /* Entries before a[iLt] are less than rPivot */ |
| 4771 | int iGt; /* Entries at or after a[iGt] are greater than rPivot */ |
| 4772 | int i; /* Loop counter */ |
| 4773 | double rPivot; /* The pivot value */ |
| 4774 | |
| 4775 | assert( n>=2 ); |
| 4776 | if( a[0]>a[n-1] ){ |
| 4777 | SWAP_DOUBLE(a[0],a[n-1]) |
| 4778 | } |
| 4779 | if( n==2 ) return; |
| 4780 | iGt = n-1; |
| 4781 | i = n/2; |
| 4782 | if( a[0]>a[i] ){ |
| 4783 | SWAP_DOUBLE(a[0],a[i]) |
| 4784 | }else if( a[i]>a[iGt] ){ |
| 4785 | SWAP_DOUBLE(a[i],a[iGt]) |
| 4786 | } |
| 4787 | if( n==3 ) return; |
| 4788 | rPivot = a[i]; |
| 4789 | iLt = i = 1; |
| 4790 | do{ |
| 4791 | if( a[i]<rPivot ){ |
| 4792 | if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt]) |
| 4793 | iLt++; |
| 4794 | i++; |
| 4795 | }else if( a[i]>rPivot ){ |
| 4796 | do{ |
| 4797 | iGt--; |
| 4798 | }while( iGt>i && a[iGt]>rPivot ); |
| 4799 | SWAP_DOUBLE(a[i],a[iGt]) |
| 4800 | }else{ |
| 4801 | i++; |
| 4802 | } |
| 4803 | }while( i<iGt ); |
| 4804 | if( iLt>=2 ) percentSort(a, iLt); |
| 4805 | if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); |
| 4806 | |
| 4807 | /* Uncomment for testing */ |
| 4808 | #if 0 |
| 4809 | for(i=0; i<n-1; i++){ |
| 4810 | assert( a[i]<=a[i+1] ); |
| 4811 | } |
| 4812 | #endif |
| 4813 | } |
| 4814 | |
| 4815 | |
| 4816 | /* |
| 4817 | ** The "inverse" function for percentile(Y,P) is called to remove a |
| 4818 | ** row that was previously inserted by "step". |
| 4819 | */ |
| 4820 | static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){ |
| 4821 | Percentile *p; |
| 4822 | int eType; |
| 4823 | double y; |
| 4824 | int i; |
| 4825 | assert( argc==2 || argc==1 ); |
| 4826 | |
| 4827 | /* Allocate the session context. */ |
| 4828 | p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 4829 | assert( p!=0 ); |
| 4830 | |
| 4831 | /* Ignore rows for which Y is NULL */ |
| 4832 | eType = sqlite3_value_type(argv[0]); |
| 4833 | if( eType==SQLITE_NULL ) return; |
| 4834 | |
| 4835 | /* If not NULL, then Y must be numeric. Otherwise throw an error. |
| 4836 | ** Requirement 4 */ |
| 4837 | if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ |
| 4838 | return; |
| 4839 | } |
| 4840 | |
| 4841 | /* Ignore the Y value if it is infinity or NaN */ |
| 4842 | y = sqlite3_value_double(argv[0]); |
| 4843 | if( percentIsInfinity(y) ){ |
| 4844 | return; |
| 4845 | } |
| 4846 | if( p->bSorted==0 ){ |
| 4847 | assert( p->nUsed>1 ); |
| 4848 | percentSort(p->a, p->nUsed); |
| 4849 | p->bSorted = 1; |
| 4850 | } |
| 4851 | p->bKeepSorted = 1; |
| 4852 | |
| 4853 | /* Find and remove the row */ |
| 4854 | i = percentBinarySearch(p, y, 1); |
| 4855 | if( i>=0 ){ |
| 4856 | p->nUsed--; |
| 4857 | if( i<(int)p->nUsed ){ |
| 4858 | memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0])); |
| 4859 | } |
| 4860 | } |
| 4861 | } |
| 4862 | |
| 4863 | /* |
| 4864 | ** Compute the final output of percentile(). Clean up all allocated |
| 4865 | ** memory if and only if bIsFinal is true. |
| 4866 | */ |
| 4867 | static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ |
| 4868 | Percentile *p; |
| 4869 | PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); |
| 4870 | unsigned i1, i2; |
| 4871 | double v1, v2; |
| 4872 | double ix, vx; |
| 4873 | p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); |
| 4874 | if( p==0 ) return; |
| 4875 | if( p->a==0 ) return; |
| 4876 | if( p->nUsed ){ |
| 4877 | if( p->bSorted==0 ){ |
| 4878 | assert( p->nUsed>1 ); |
| 4879 | percentSort(p->a, p->nUsed); |
| 4880 | p->bSorted = 1; |
| 4881 | } |
| 4882 | ix = p->rPct*(p->nUsed-1); |
| 4883 | i1 = (unsigned)ix; |
| 4884 | if( pFunc->bDiscrete ){ |
| 4885 | vx = p->a[i1]; |
| 4886 | }else{ |
| 4887 | i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; |
| 4888 | v1 = p->a[i1]; |
| 4889 | v2 = p->a[i2]; |
| 4890 | vx = v1 + (v2-v1)*(ix-i1); |
| 4891 | } |
| 4892 | sqlite3_result_double(pCtx, vx); |
| 4893 | } |
| 4894 | if( bIsFinal ){ |
| 4895 | sqlite3_free(p->a); |
| 4896 | memset(p, 0, sizeof(*p)); |
| 4897 | }else{ |
| 4898 | p->bKeepSorted = 1; |
| 4899 | } |
| 4900 | } |
| 4901 | static void percentFinal(sqlite3_context *pCtx){ |
| 4902 | percentCompute(pCtx, 1); |
| 4903 | } |
| 4904 | static void percentValue(sqlite3_context *pCtx){ |
| 4905 | percentCompute(pCtx, 0); |
| 4906 | } |
| 4907 | |
| 4908 | #if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE) |
| 4909 | |
| 4910 | #endif |
| 4911 | int sqlite3_percentile_init( |
| 4912 | sqlite3 *db, |
| 4913 | char **pzErrMsg, |
| 4914 | const sqlite3_api_routines *pApi |
| 4915 | ){ |
| 4916 | int rc = SQLITE_OK; |
| 4917 | unsigned int i; |
| 4918 | #ifdef SQLITE3EXT_H |
| 4919 | SQLITE_EXTENSION_INIT2(pApi); |
| 4920 | #else |
| 4921 | (void)pApi; /* Unused parameter */ |
| 4922 | #endif |
| 4923 | (void)pzErrMsg; /* Unused parameter */ |
| 4924 | for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){ |
| 4925 | rc = sqlite3_create_window_function(db, |
| 4926 | aPercentFunc[i].zName, |
| 4927 | aPercentFunc[i].nArg, |
| 4928 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1, |
| 4929 | (void*)&aPercentFunc[i], |
| 4930 | percentStep, percentFinal, percentValue, percentInverse, 0); |
| 4931 | if( rc ) break; |
| 4932 | } |
| 4933 | return rc; |
| 4934 | } |
| 4935 | |
| 4936 | /************************* End ../ext/misc/percentile.c ********************/ |
| 4937 | #undef sqlite3_base_init |
| 4938 | #define sqlite3_base_init sqlite3_base64_init |
| 4939 | /************************* Begin ../ext/misc/base64.c ******************/ |
| 4940 | /* |
| 4941 | ** 2022-11-18 |
| @@ -5144,20 +4710,22 @@ | |
| 5144 | return pOut; |
| 5145 | } |
| 5146 | |
| 5147 | /* This function does the work for the SQLite base64(x) UDF. */ |
| 5148 | static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){ |
| 5149 | int nb, nc, nv = sqlite3_value_bytes(av[0]); |
| 5150 | int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), |
| 5151 | SQLITE_LIMIT_LENGTH, -1); |
| 5152 | char *cBuf; |
| 5153 | u8 *bBuf; |
| 5154 | assert(na==1); |
| 5155 | switch( sqlite3_value_type(av[0]) ){ |
| 5156 | case SQLITE_BLOB: |
| 5157 | nb = nv; |
| 5158 | nc = 4*(nv+2/3); /* quads needed */ |
| 5159 | nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */ |
| 5160 | if( nvMax < nc ){ |
| 5161 | sqlite3_result_error(context, "blob expanded to base64 too big", -1); |
| 5162 | return; |
| 5163 | } |
| @@ -5524,11 +5092,11 @@ | |
| 5524 | } |
| 5525 | # endif |
| 5526 | |
| 5527 | /* This function does the work for the SQLite base85(x) UDF. */ |
| 5528 | static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){ |
| 5529 | int nb, nc, nv = sqlite3_value_bytes(av[0]); |
| 5530 | int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), |
| 5531 | SQLITE_LIMIT_LENGTH, -1); |
| 5532 | char *cBuf; |
| 5533 | u8 *bBuf; |
| 5534 | assert(na==1); |
| @@ -5829,10 +5397,13 @@ | |
| 5829 | } |
| 5830 | memcpy(&a,&r,sizeof(a)); |
| 5831 | if( a==0 ){ |
| 5832 | e = 0; |
| 5833 | m = 0; |
| 5834 | }else{ |
| 5835 | e = a>>52; |
| 5836 | m = a & ((((sqlite3_int64)1)<<52)-1); |
| 5837 | if( e==0 ){ |
| 5838 | m <<= 1; |
| @@ -6052,23 +5623,24 @@ | |
| 6052 | ** Examples: |
| 6053 | ** |
| 6054 | ** SELECT * FROM generate_series(0,100,5); |
| 6055 | ** |
| 6056 | ** The query above returns integers from 0 through 100 counting by steps |
| 6057 | ** of 5. |
| 6058 | ** |
| 6059 | ** SELECT * FROM generate_series(0,100); |
| 6060 | ** |
| 6061 | ** Integers from 0 through 100 with a step size of 1. |
| 6062 | ** |
| 6063 | ** SELECT * FROM generate_series(20) LIMIT 10; |
| 6064 | ** |
| 6065 | ** Integers 20 through 29. |
| 6066 | ** |
| 6067 | ** SELECT * FROM generate_series(0,-100,-5); |
| 6068 | ** |
| 6069 | ** Integers 0 -5 -10 ... -100. |
| 6070 | ** |
| 6071 | ** SELECT * FROM generate_series(0,-1); |
| 6072 | ** |
| 6073 | ** Empty sequence. |
| 6074 | ** |
| @@ -6140,143 +5712,92 @@ | |
| 6140 | #include <string.h> |
| 6141 | #include <limits.h> |
| 6142 | #include <math.h> |
| 6143 | |
| 6144 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 6145 | /* |
| 6146 | ** Return that member of a generate_series(...) sequence whose 0-based |
| 6147 | ** index is ix. The 0th member is given by smBase. The sequence members |
| 6148 | ** progress per ix increment by smStep. |
| 6149 | */ |
| 6150 | static sqlite3_int64 genSeqMember( |
| 6151 | sqlite3_int64 smBase, |
| 6152 | sqlite3_int64 smStep, |
| 6153 | sqlite3_uint64 ix |
| 6154 | ){ |
| 6155 | static const sqlite3_uint64 mxI64 = |
| 6156 | ((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff; |
| 6157 | if( ix>=mxI64 ){ |
| 6158 | /* Get ix into signed i64 range. */ |
| 6159 | ix -= mxI64; |
| 6160 | /* With 2's complement ALU, this next can be 1 step, but is split into |
| 6161 | * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */ |
| 6162 | smBase += (mxI64/2) * smStep; |
| 6163 | smBase += (mxI64 - mxI64/2) * smStep; |
| 6164 | } |
| 6165 | /* Under UBSAN (or on 1's complement machines), must do this last term |
| 6166 | * in steps to avoid the dreaded (and harmless) signed multiply overflow. */ |
| 6167 | if( ix>=2 ){ |
| 6168 | sqlite3_int64 ix2 = (sqlite3_int64)ix/2; |
| 6169 | smBase += ix2*smStep; |
| 6170 | ix -= ix2; |
| 6171 | } |
| 6172 | return smBase + ((sqlite3_int64)ix)*smStep; |
| 6173 | } |
| 6174 | |
| 6175 | /* typedef unsigned char u8; */ |
| 6176 | |
| 6177 | typedef struct SequenceSpec { |
| 6178 | sqlite3_int64 iOBase; /* Original starting value ("start") */ |
| 6179 | sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ |
| 6180 | sqlite3_int64 iBase; /* Starting value to actually use */ |
| 6181 | sqlite3_int64 iTerm; /* Terminal value to actually use */ |
| 6182 | sqlite3_int64 iStep; /* Increment ("step") */ |
| 6183 | sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */ |
| 6184 | sqlite3_uint64 uSeqIndexNow; /* Current index during generation */ |
| 6185 | sqlite3_int64 iValueNow; /* Current value during generation */ |
| 6186 | u8 isNotEOF; /* Sequence generation not exhausted */ |
| 6187 | u8 isReversing; /* Sequence is being reverse generated */ |
| 6188 | } SequenceSpec; |
| 6189 | |
| 6190 | /* |
| 6191 | ** Prepare a SequenceSpec for use in generating an integer series |
| 6192 | ** given initialized iBase, iTerm and iStep values. Sequence is |
| 6193 | ** initialized per given isReversing. Other members are computed. |
| 6194 | */ |
| 6195 | static void setupSequence( SequenceSpec *pss ){ |
| 6196 | int bSameSigns; |
| 6197 | pss->uSeqIndexMax = 0; |
| 6198 | pss->isNotEOF = 0; |
| 6199 | bSameSigns = (pss->iBase < 0)==(pss->iTerm < 0); |
| 6200 | if( pss->iTerm < pss->iBase ){ |
| 6201 | sqlite3_uint64 nuspan = 0; |
| 6202 | if( bSameSigns ){ |
| 6203 | nuspan = (sqlite3_uint64)(pss->iBase - pss->iTerm); |
| 6204 | }else{ |
| 6205 | /* Under UBSAN (or on 1's complement machines), must do this in steps. |
| 6206 | * In this clause, iBase>=0 and iTerm<0 . */ |
| 6207 | nuspan = 1; |
| 6208 | nuspan += pss->iBase; |
| 6209 | nuspan += -(pss->iTerm+1); |
| 6210 | } |
| 6211 | if( pss->iStep<0 ){ |
| 6212 | pss->isNotEOF = 1; |
| 6213 | if( nuspan==ULONG_MAX ){ |
| 6214 | pss->uSeqIndexMax = ( pss->iStep>LLONG_MIN )? nuspan/-pss->iStep : 1; |
| 6215 | }else if( pss->iStep>LLONG_MIN ){ |
| 6216 | pss->uSeqIndexMax = nuspan/-pss->iStep; |
| 6217 | } |
| 6218 | } |
| 6219 | }else if( pss->iTerm > pss->iBase ){ |
| 6220 | sqlite3_uint64 puspan = 0; |
| 6221 | if( bSameSigns ){ |
| 6222 | puspan = (sqlite3_uint64)(pss->iTerm - pss->iBase); |
| 6223 | }else{ |
| 6224 | /* Under UBSAN (or on 1's complement machines), must do this in steps. |
| 6225 | * In this clause, iTerm>=0 and iBase<0 . */ |
| 6226 | puspan = 1; |
| 6227 | puspan += pss->iTerm; |
| 6228 | puspan += -(pss->iBase+1); |
| 6229 | } |
| 6230 | if( pss->iStep>0 ){ |
| 6231 | pss->isNotEOF = 1; |
| 6232 | pss->uSeqIndexMax = puspan/pss->iStep; |
| 6233 | } |
| 6234 | }else if( pss->iTerm == pss->iBase ){ |
| 6235 | pss->isNotEOF = 1; |
| 6236 | pss->uSeqIndexMax = 0; |
| 6237 | } |
| 6238 | pss->uSeqIndexNow = (pss->isReversing)? pss->uSeqIndexMax : 0; |
| 6239 | pss->iValueNow = (pss->isReversing) |
| 6240 | ? genSeqMember(pss->iBase, pss->iStep, pss->uSeqIndexMax) |
| 6241 | : pss->iBase; |
| 6242 | } |
| 6243 | |
| 6244 | /* |
| 6245 | ** Progress sequence generator to yield next value, if any. |
| 6246 | ** Leave its state to either yield next value or be at EOF. |
| 6247 | ** Return whether there is a next value, or 0 at EOF. |
| 6248 | */ |
| 6249 | static int progressSequence( SequenceSpec *pss ){ |
| 6250 | if( !pss->isNotEOF ) return 0; |
| 6251 | if( pss->isReversing ){ |
| 6252 | if( pss->uSeqIndexNow > 0 ){ |
| 6253 | pss->uSeqIndexNow--; |
| 6254 | pss->iValueNow -= pss->iStep; |
| 6255 | }else{ |
| 6256 | pss->isNotEOF = 0; |
| 6257 | } |
| 6258 | }else{ |
| 6259 | if( pss->uSeqIndexNow < pss->uSeqIndexMax ){ |
| 6260 | pss->uSeqIndexNow++; |
| 6261 | pss->iValueNow += pss->iStep; |
| 6262 | }else{ |
| 6263 | pss->isNotEOF = 0; |
| 6264 | } |
| 6265 | } |
| 6266 | return pss->isNotEOF; |
| 6267 | } |
| 6268 | |
| 6269 | /* series_cursor is a subclass of sqlite3_vtab_cursor which will |
| 6270 | ** serve as the underlying representation of a cursor that scans |
| 6271 | ** over rows of the result |
| 6272 | */ |
| 6273 | typedef struct series_cursor series_cursor; |
| 6274 | struct series_cursor { |
| 6275 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 6276 | SequenceSpec ss; /* (this) Derived class data */ |
| 6277 | }; |
| 6278 | |
| 6279 | /* |
| 6280 | ** The seriesConnect() method is invoked to create a new |
| 6281 | ** series_vtab that describes the generate_series virtual table. |
| 6282 | ** |
| @@ -6354,11 +5875,19 @@ | |
| 6354 | /* |
| 6355 | ** Advance a series_cursor to its next row of output. |
| 6356 | */ |
| 6357 | static int seriesNext(sqlite3_vtab_cursor *cur){ |
| 6358 | series_cursor *pCur = (series_cursor*)cur; |
| 6359 | progressSequence( & pCur->ss ); |
| 6360 | return SQLITE_OK; |
| 6361 | } |
| 6362 | |
| 6363 | /* |
| 6364 | ** Return values of columns for the row at which the series_cursor |
| @@ -6370,41 +5899,41 @@ | |
| 6370 | int i /* Which column to return */ |
| 6371 | ){ |
| 6372 | series_cursor *pCur = (series_cursor*)cur; |
| 6373 | sqlite3_int64 x = 0; |
| 6374 | switch( i ){ |
| 6375 | case SERIES_COLUMN_START: x = pCur->ss.iOBase; break; |
| 6376 | case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break; |
| 6377 | case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; |
| 6378 | default: x = pCur->ss.iValueNow; break; |
| 6379 | } |
| 6380 | sqlite3_result_int64(ctx, x); |
| 6381 | return SQLITE_OK; |
| 6382 | } |
| 6383 | |
| 6384 | #ifndef LARGEST_UINT64 |
| 6385 | #define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) |
| 6386 | #define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) |
| 6387 | #define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) |
| 6388 | #endif |
| 6389 | |
| 6390 | /* |
| 6391 | ** The rowid is the same as the value. |
| 6392 | */ |
| 6393 | static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 6394 | series_cursor *pCur = (series_cursor*)cur; |
| 6395 | *pRowid = pCur->ss.iValueNow; |
| 6396 | return SQLITE_OK; |
| 6397 | } |
| 6398 | |
| 6399 | /* |
| 6400 | ** Return TRUE if the cursor has been moved off of the last |
| 6401 | ** row of output. |
| 6402 | */ |
| 6403 | static int seriesEof(sqlite3_vtab_cursor *cur){ |
| 6404 | series_cursor *pCur = (series_cursor*)cur; |
| 6405 | return !pCur->ss.isNotEOF; |
| 6406 | } |
| 6407 | |
| 6408 | /* True to cause run-time checking of the start=, stop=, and/or step= |
| 6409 | ** parameters. The only reason to do this is for testing the |
| 6410 | ** constraint checking logic for virtual tables in the SQLite core. |
| @@ -6411,10 +5940,63 @@ | |
| 6411 | */ |
| 6412 | #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY |
| 6413 | # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 |
| 6414 | #endif |
| 6415 | |
| 6416 | /* |
| 6417 | ** This method is called to "rewind" the series_cursor object back |
| 6418 | ** to the first row of output. This method is always called at least |
| 6419 | ** once prior to any call to seriesColumn() or seriesRowid() or |
| 6420 | ** seriesEof(). |
| @@ -6444,185 +6026,243 @@ | |
| 6444 | sqlite3_vtab_cursor *pVtabCursor, |
| 6445 | int idxNum, const char *idxStrUnused, |
| 6446 | int argc, sqlite3_value **argv |
| 6447 | ){ |
| 6448 | series_cursor *pCur = (series_cursor *)pVtabCursor; |
| 6449 | int i = 0; |
| 6450 | int returnNoRows = 0; |
| 6451 | sqlite3_int64 iMin = SMALLEST_INT64; |
| 6452 | sqlite3_int64 iMax = LARGEST_INT64; |
| 6453 | sqlite3_int64 iLimit = 0; |
| 6454 | sqlite3_int64 iOffset = 0; |
| 6455 | |
| 6456 | (void)idxStrUnused; |
| 6457 | if( idxNum & 0x01 ){ |
| 6458 | pCur->ss.iBase = sqlite3_value_int64(argv[i++]); |
| 6459 | }else{ |
| 6460 | pCur->ss.iBase = 0; |
| 6461 | } |
| 6462 | if( idxNum & 0x02 ){ |
| 6463 | pCur->ss.iTerm = sqlite3_value_int64(argv[i++]); |
| 6464 | }else{ |
| 6465 | pCur->ss.iTerm = 0xffffffff; |
| 6466 | } |
| 6467 | if( idxNum & 0x04 ){ |
| 6468 | pCur->ss.iStep = sqlite3_value_int64(argv[i++]); |
| 6469 | if( pCur->ss.iStep==0 ){ |
| 6470 | pCur->ss.iStep = 1; |
| 6471 | }else if( pCur->ss.iStep<0 ){ |
| 6472 | if( (idxNum & 0x10)==0 ) idxNum |= 0x08; |
| 6473 | } |
| 6474 | }else{ |
| 6475 | pCur->ss.iStep = 1; |
| 6476 | } |
| 6477 | |
| 6478 | /* If there are constraints on the value column but there are |
| 6479 | ** no constraints on the start, stop, and step columns, then |
| 6480 | ** initialize the default range to be the entire range of 64-bit signed |
| 6481 | ** integers. This range will contracted by the value column constraints |
| 6482 | ** further below. |
| 6483 | */ |
| 6484 | if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ |
| 6485 | pCur->ss.iBase = SMALLEST_INT64; |
| 6486 | } |
| 6487 | if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ |
| 6488 | pCur->ss.iTerm = LARGEST_INT64; |
| 6489 | } |
| 6490 | pCur->ss.iOBase = pCur->ss.iBase; |
| 6491 | pCur->ss.iOTerm = pCur->ss.iTerm; |
| 6492 | |
| 6493 | /* Extract the LIMIT and OFFSET values, but do not apply them yet. |
| 6494 | ** The range must first be constrained by the limits on value. |
| 6495 | */ |
| 6496 | if( idxNum & 0x20 ){ |
| 6497 | iLimit = sqlite3_value_int64(argv[i++]); |
| 6498 | if( idxNum & 0x40 ){ |
| 6499 | iOffset = sqlite3_value_int64(argv[i++]); |
| 6500 | } |
| 6501 | } |
| 6502 | |
| 6503 | if( idxNum & 0x3380 ){ |
| 6504 | /* Extract the maximum range of output values determined by |
| 6505 | ** constraints on the "value" column. |
| 6506 | */ |
| 6507 | if( idxNum & 0x0080 ){ |
| 6508 | if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ |
| 6509 | double r = sqlite3_value_double(argv[i++]); |
| 6510 | if( r==ceil(r) ){ |
| 6511 | iMin = iMax = (sqlite3_int64)r; |
| 6512 | }else{ |
| 6513 | returnNoRows = 1; |
| 6514 | } |
| 6515 | }else{ |
| 6516 | iMin = iMax = sqlite3_value_int64(argv[i++]); |
| 6517 | } |
| 6518 | }else{ |
| 6519 | if( idxNum & 0x0300 ){ |
| 6520 | if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ |
| 6521 | double r = sqlite3_value_double(argv[i++]); |
| 6522 | if( idxNum & 0x0200 && r==ceil(r) ){ |
| 6523 | iMin = (sqlite3_int64)ceil(r+1.0); |
| 6524 | }else{ |
| 6525 | iMin = (sqlite3_int64)ceil(r); |
| 6526 | } |
| 6527 | }else{ |
| 6528 | iMin = sqlite3_value_int64(argv[i++]); |
| 6529 | if( idxNum & 0x0200 ){ |
| 6530 | if( iMin==LARGEST_INT64 ){ |
| 6531 | returnNoRows = 1; |
| 6532 | }else{ |
| 6533 | iMin++; |
| 6534 | } |
| 6535 | } |
| 6536 | } |
| 6537 | } |
| 6538 | if( idxNum & 0x3000 ){ |
| 6539 | if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ |
| 6540 | double r = sqlite3_value_double(argv[i++]); |
| 6541 | if( (idxNum & 0x2000)!=0 && r==floor(r) ){ |
| 6542 | iMax = (sqlite3_int64)(r-1.0); |
| 6543 | }else{ |
| 6544 | iMax = (sqlite3_int64)floor(r); |
| 6545 | } |
| 6546 | }else{ |
| 6547 | iMax = sqlite3_value_int64(argv[i++]); |
| 6548 | if( idxNum & 0x2000 ){ |
| 6549 | if( iMax==SMALLEST_INT64 ){ |
| 6550 | returnNoRows = 1; |
| 6551 | }else{ |
| 6552 | iMax--; |
| 6553 | } |
| 6554 | } |
| 6555 | } |
| 6556 | } |
| 6557 | if( iMin>iMax ){ |
| 6558 | returnNoRows = 1; |
| 6559 | } |
| 6560 | } |
| 6561 | |
| 6562 | /* Try to reduce the range of values to be generated based on |
| 6563 | ** constraints on the "value" column. |
| 6564 | */ |
| 6565 | if( pCur->ss.iStep>0 ){ |
| 6566 | sqlite3_int64 szStep = pCur->ss.iStep; |
| 6567 | if( pCur->ss.iBase<iMin ){ |
| 6568 | sqlite3_uint64 d = iMin - pCur->ss.iBase; |
| 6569 | pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; |
| 6570 | } |
| 6571 | if( pCur->ss.iTerm>iMax ){ |
| 6572 | pCur->ss.iTerm = iMax; |
| 6573 | } |
| 6574 | }else{ |
| 6575 | sqlite3_int64 szStep = -pCur->ss.iStep; |
| 6576 | assert( szStep>0 ); |
| 6577 | if( pCur->ss.iBase>iMax ){ |
| 6578 | sqlite3_uint64 d = pCur->ss.iBase - iMax; |
| 6579 | pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; |
| 6580 | } |
| 6581 | if( pCur->ss.iTerm<iMin ){ |
| 6582 | pCur->ss.iTerm = iMin; |
| 6583 | } |
| 6584 | } |
| 6585 | } |
| 6586 | |
| 6587 | /* Apply LIMIT and OFFSET constraints, if any */ |
| 6588 | if( idxNum & 0x20 ){ |
| 6589 | if( iOffset>0 ){ |
| 6590 | pCur->ss.iBase += pCur->ss.iStep*iOffset; |
| 6591 | } |
| 6592 | if( iLimit>=0 ){ |
| 6593 | sqlite3_int64 iTerm; |
| 6594 | iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; |
| 6595 | if( pCur->ss.iStep<0 ){ |
| 6596 | if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; |
| 6597 | }else{ |
| 6598 | if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; |
| 6599 | } |
| 6600 | } |
| 6601 | } |
| 6602 | |
| 6603 | |
| 6604 | for(i=0; i<argc; i++){ |
| 6605 | if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ |
| 6606 | /* If any of the constraints have a NULL value, then return no rows. |
| 6607 | ** See ticket https://sqlite.org/src/info/fac496b61722daf2 */ |
| 6608 | returnNoRows = 1; |
| 6609 | break; |
| 6610 | } |
| 6611 | } |
| 6612 | if( returnNoRows ){ |
| 6613 | pCur->ss.iBase = 1; |
| 6614 | pCur->ss.iTerm = 0; |
| 6615 | pCur->ss.iStep = 1; |
| 6616 | } |
| 6617 | if( idxNum & 0x08 ){ |
| 6618 | pCur->ss.isReversing = pCur->ss.iStep > 0; |
| 6619 | }else{ |
| 6620 | pCur->ss.isReversing = pCur->ss.iStep < 0; |
| 6621 | } |
| 6622 | setupSequence( &pCur->ss ); |
| 6623 | return SQLITE_OK; |
| 6624 | } |
| 6625 | |
| 6626 | /* |
| 6627 | ** SQLite will invoke this method one or more times while planning a query |
| 6628 | ** that uses the generate_series virtual table. This routine needs to create |
| @@ -6948,10 +6588,12 @@ | |
| 6948 | ** expression and M is the size of the input string. The matcher never |
| 6949 | ** exhibits exponential behavior. Note that the X{p,q} operator expands |
| 6950 | ** to p copies of X following by q-p copies of X? and that the size of the |
| 6951 | ** regular expression in the O(N*M) performance bound is computed after |
| 6952 | ** this expansion. |
| 6953 | */ |
| 6954 | #include <string.h> |
| 6955 | #include <stdlib.h> |
| 6956 | /* #include "sqlite3ext.h" */ |
| 6957 | SQLITE_EXTENSION_INIT1 |
| @@ -6988,36 +6630,10 @@ | |
| 6988 | #define RE_OP_NOTDIGIT 14 /* Not a digit */ |
| 6989 | #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ |
| 6990 | #define RE_OP_NOTSPACE 16 /* Not a digit */ |
| 6991 | #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ |
| 6992 | #define RE_OP_ATSTART 18 /* Currently at the start of the string */ |
| 6993 | |
| 6994 | #if defined(SQLITE_DEBUG) |
| 6995 | /* Opcode names used for symbolic debugging */ |
| 6996 | static const char *ReOpName[] = { |
| 6997 | "EOF", |
| 6998 | "MATCH", |
| 6999 | "ANY", |
| 7000 | "ANYSTAR", |
| 7001 | "FORK", |
| 7002 | "GOTO", |
| 7003 | "ACCEPT", |
| 7004 | "CC_INC", |
| 7005 | "CC_EXC", |
| 7006 | "CC_VALUE", |
| 7007 | "CC_RANGE", |
| 7008 | "WORD", |
| 7009 | "NOTWORD", |
| 7010 | "DIGIT", |
| 7011 | "NOTDIGIT", |
| 7012 | "SPACE", |
| 7013 | "NOTSPACE", |
| 7014 | "BOUNDARY", |
| 7015 | "ATSTART", |
| 7016 | }; |
| 7017 | #endif /* SQLITE_DEBUG */ |
| 7018 | |
| 7019 | |
| 7020 | /* Each opcode is a "state" in the NFA */ |
| 7021 | typedef unsigned short ReStateNumber; |
| 7022 | |
| 7023 | /* Because this is an NFA and not a DFA, multiple states can be active at |
| @@ -7051,10 +6667,11 @@ | |
| 7051 | unsigned (*xNextChar)(ReInput*); /* Next character function */ |
| 7052 | unsigned char zInit[12]; /* Initial text to match */ |
| 7053 | int nInit; /* Number of bytes in zInit */ |
| 7054 | unsigned nState; /* Number of entries in aOp[] and aArg[] */ |
| 7055 | unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */ |
| 7056 | }; |
| 7057 | |
| 7058 | /* Add a state to the given state set if it is not already there */ |
| 7059 | static void re_add_state(ReStateSet *pSet, int newState){ |
| 7060 | unsigned i; |
| @@ -7265,18 +6882,19 @@ | |
| 7265 | return rc; |
| 7266 | } |
| 7267 | |
| 7268 | /* Resize the opcode and argument arrays for an RE under construction. |
| 7269 | */ |
| 7270 | static int re_resize(ReCompiled *p, int N){ |
| 7271 | char *aOp; |
| 7272 | int *aArg; |
| 7273 | aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0])); |
| 7274 | if( aOp==0 ) return 1; |
| 7275 | p->aOp = aOp; |
| 7276 | aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0])); |
| 7277 | if( aArg==0 ) return 1; |
| 7278 | p->aArg = aArg; |
| 7279 | p->nAlloc = N; |
| 7280 | return 0; |
| 7281 | } |
| 7282 | |
| @@ -7303,11 +6921,11 @@ | |
| 7303 | } |
| 7304 | |
| 7305 | /* Make a copy of N opcodes starting at iStart onto the end of the RE |
| 7306 | ** under construction. |
| 7307 | */ |
| 7308 | static void re_copy(ReCompiled *p, int iStart, int N){ |
| 7309 | if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return; |
| 7310 | memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0])); |
| 7311 | memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0])); |
| 7312 | p->nState += N; |
| 7313 | } |
| @@ -7456,22 +7074,30 @@ | |
| 7456 | case '^': { |
| 7457 | re_append(p, RE_OP_ATSTART, 0); |
| 7458 | break; |
| 7459 | } |
| 7460 | case '{': { |
| 7461 | int m = 0, n = 0; |
| 7462 | int sz, j; |
| 7463 | if( iPrev<0 ) return "'{m,n}' without operand"; |
| 7464 | while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; } |
| 7465 | n = m; |
| 7466 | if( c==',' ){ |
| 7467 | p->sIn.i++; |
| 7468 | n = 0; |
| 7469 | while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; } |
| 7470 | } |
| 7471 | if( c!='}' ) return "unmatched '{'"; |
| 7472 | if( n>0 && n<m ) return "n less than m in '{m,n}'"; |
| 7473 | p->sIn.i++; |
| 7474 | sz = p->nState - iPrev; |
| 7475 | if( m==0 ){ |
| 7476 | if( n==0 ) return "both m and n are zero in '{m,n}'"; |
| 7477 | re_insert(p, iPrev, RE_OP_FORK, sz+1); |
| @@ -7483,11 +7109,11 @@ | |
| 7483 | for(j=m; j<n; j++){ |
| 7484 | re_append(p, RE_OP_FORK, sz+1); |
| 7485 | re_copy(p, iPrev, sz); |
| 7486 | } |
| 7487 | if( n==0 && m>0 ){ |
| 7488 | re_append(p, RE_OP_FORK, -sz); |
| 7489 | } |
| 7490 | break; |
| 7491 | } |
| 7492 | case '[': { |
| 7493 | unsigned int iFirst = p->nState; |
| @@ -7549,12 +7175,11 @@ | |
| 7549 | |
| 7550 | /* Free and reclaim all the memory used by a previously compiled |
| 7551 | ** regular expression. Applications should invoke this routine once |
| 7552 | ** for every call to re_compile() to avoid memory leaks. |
| 7553 | */ |
| 7554 | static void re_free(void *p){ |
| 7555 | ReCompiled *pRe = (ReCompiled*)p; |
| 7556 | if( pRe ){ |
| 7557 | sqlite3_free(pRe->aOp); |
| 7558 | sqlite3_free(pRe->aArg); |
| 7559 | sqlite3_free(pRe); |
| 7560 | } |
| @@ -7564,11 +7189,16 @@ | |
| 7564 | ** Compile a textual regular expression in zIn[] into a compiled regular |
| 7565 | ** expression suitable for us by re_match() and return a pointer to the |
| 7566 | ** compiled regular expression in *ppRe. Return NULL on success or an |
| 7567 | ** error message if something goes wrong. |
| 7568 | */ |
| 7569 | static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ |
| 7570 | ReCompiled *pRe; |
| 7571 | const char *zErr; |
| 7572 | int i, j; |
| 7573 | |
| 7574 | *ppRe = 0; |
| @@ -7576,13 +7206,15 @@ | |
| 7576 | if( pRe==0 ){ |
| 7577 | return "out of memory"; |
| 7578 | } |
| 7579 | memset(pRe, 0, sizeof(*pRe)); |
| 7580 | pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char; |
| 7581 | if( re_resize(pRe, 30) ){ |
| 7582 | re_free(pRe); |
| 7583 | return "out of memory"; |
| 7584 | } |
| 7585 | if( zIn[0]=='^' ){ |
| 7586 | zIn++; |
| 7587 | }else{ |
| 7588 | re_append(pRe, RE_OP_ANYSTAR, 0); |
| @@ -7630,10 +7262,18 @@ | |
| 7630 | if( j>0 && pRe->zInit[j-1]==0 ) j--; |
| 7631 | pRe->nInit = j; |
| 7632 | } |
| 7633 | return pRe->zErr; |
| 7634 | } |
| 7635 | |
| 7636 | /* |
| 7637 | ** Implementation of the regexp() SQL function. This function implements |
| 7638 | ** the build-in REGEXP operator. The first argument to the function is the |
| 7639 | ** pattern and the second argument is the string. So, the SQL statements: |
| @@ -7656,11 +7296,12 @@ | |
| 7656 | (void)argc; /* Unused */ |
| 7657 | pRe = sqlite3_get_auxdata(context, 0); |
| 7658 | if( pRe==0 ){ |
| 7659 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 7660 | if( zPattern==0 ) return; |
| 7661 | zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); |
| 7662 | if( zErr ){ |
| 7663 | re_free(pRe); |
| 7664 | sqlite3_result_error(context, zErr, -1); |
| 7665 | return; |
| 7666 | } |
| @@ -7698,14 +7339,36 @@ | |
| 7698 | sqlite3_str *pStr; |
| 7699 | int i; |
| 7700 | int n; |
| 7701 | char *z; |
| 7702 | (void)argc; |
| 7703 | |
| 7704 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 7705 | if( zPattern==0 ) return; |
| 7706 | zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); |
| 7707 | if( zErr ){ |
| 7708 | re_free(pRe); |
| 7709 | sqlite3_result_error(context, zErr, -1); |
| 7710 | return; |
| 7711 | } |
| @@ -9284,18 +8947,20 @@ | |
| 9284 | if( idxNum & 1 ){ |
| 9285 | pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); |
| 9286 | if( pCur->nPrefix>0 ){ |
| 9287 | pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 9288 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 9289 | } |
| 9290 | iArg = 1; |
| 9291 | } |
| 9292 | if( idxNum & 2 ){ |
| 9293 | pCur->nLine = sqlite3_value_bytes(argv[iArg]); |
| 9294 | if( pCur->nLine>0 ){ |
| 9295 | pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 9296 | if( pCur->zLine==0 ) return SQLITE_NOMEM; |
| 9297 | } |
| 9298 | } |
| 9299 | if( pCur->zLine!=0 && pCur->zPrefix==0 ){ |
| 9300 | int i = pCur->nLine; |
| 9301 | while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ |
| @@ -9303,10 +8968,11 @@ | |
| 9303 | } |
| 9304 | pCur->nPrefix = pCur->nLine - i; |
| 9305 | if( pCur->nPrefix>0 ){ |
| 9306 | pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); |
| 9307 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 9308 | } |
| 9309 | } |
| 9310 | pCur->iRowid = 0; |
| 9311 | pCur->ePhase = COMPLETION_FIRST_PHASE; |
| 9312 | return completionNext(pVtabCursor); |
| @@ -10216,11 +9882,17 @@ | |
| 10216 | "method," /* 6: Compression method (integer) */ |
| 10217 | "z HIDDEN" /* 7: Name of zip file */ |
| 10218 | ") WITHOUT ROWID;"; |
| 10219 | |
| 10220 | #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ |
| 10221 | #define ZIPFILE_BUFFER_SIZE (64*1024) |
| 10222 | |
| 10223 | |
| 10224 | /* |
| 10225 | ** Magic numbers used to read and write zip files. |
| 10226 | ** |
| @@ -10773,10 +10445,11 @@ | |
| 10773 | pLFH->crc32 = zipfileRead32(aRead); |
| 10774 | pLFH->szCompressed = zipfileRead32(aRead); |
| 10775 | pLFH->szUncompressed = zipfileRead32(aRead); |
| 10776 | pLFH->nFile = zipfileRead16(aRead); |
| 10777 | pLFH->nExtra = zipfileRead16(aRead); |
| 10778 | } |
| 10779 | return rc; |
| 10780 | } |
| 10781 | |
| 10782 | |
| @@ -10898,10 +10571,19 @@ | |
| 10898 | || mUnixTime==zipfileMtime(pCds) |
| 10899 | || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) |
| 10900 | /* || (mUnixTime % 2) */ |
| 10901 | ); |
| 10902 | } |
| 10903 | |
| 10904 | /* |
| 10905 | ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in |
| 10906 | ** size) containing an entire zip archive image. Or, if aBlob is NULL, |
| 10907 | ** then pFile is a file-handle open on a zip file. In either case, this |
| @@ -10921,16 +10603,19 @@ | |
| 10921 | ZipfileEntry **ppEntry /* OUT: Pointer to new object */ |
| 10922 | ){ |
| 10923 | u8 *aRead; |
| 10924 | char **pzErr = &pTab->base.zErrMsg; |
| 10925 | int rc = SQLITE_OK; |
| 10926 | (void)nBlob; |
| 10927 | |
| 10928 | if( aBlob==0 ){ |
| 10929 | aRead = pTab->aBuffer; |
| 10930 | rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); |
| 10931 | }else{ |
| 10932 | aRead = (u8*)&aBlob[iOff]; |
| 10933 | } |
| 10934 | |
| 10935 | if( rc==SQLITE_OK ){ |
| 10936 | sqlite3_int64 nAlloc; |
| @@ -10957,10 +10642,13 @@ | |
| 10957 | rc = zipfileReadData( |
| 10958 | pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr |
| 10959 | ); |
| 10960 | }else{ |
| 10961 | aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; |
| 10962 | } |
| 10963 | } |
| 10964 | |
| 10965 | if( rc==SQLITE_OK ){ |
| 10966 | u32 *pt = &pNew->mUnixTime; |
| @@ -10979,19 +10667,26 @@ | |
| 10979 | ZipfileLFH lfh; |
| 10980 | if( pFile ){ |
| 10981 | rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); |
| 10982 | }else{ |
| 10983 | aRead = (u8*)&aBlob[pNew->cds.iOffset]; |
| 10984 | } |
| 10985 | |
| 10986 | if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh); |
| 10987 | if( rc==SQLITE_OK ){ |
| 10988 | pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; |
| 10989 | pNew->iDataOff += lfh.nFile + lfh.nExtra; |
| 10990 | if( aBlob && pNew->cds.szCompressed ){ |
| 10991 | pNew->aData = &pNew->aExtra[nExtra]; |
| 10992 | memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); |
| 10993 | } |
| 10994 | }else{ |
| 10995 | *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", |
| 10996 | (int)pNew->cds.iOffset |
| 10997 | ); |
| @@ -11774,10 +11469,15 @@ | |
| 11774 | |
| 11775 | if( rc==SQLITE_OK ){ |
| 11776 | zPath = (const char*)sqlite3_value_text(apVal[2]); |
| 11777 | if( zPath==0 ) zPath = ""; |
| 11778 | nPath = (int)strlen(zPath); |
| 11779 | mTime = zipfileGetTime(apVal[4]); |
| 11780 | } |
| 11781 | |
| 11782 | if( rc==SQLITE_OK && bIsDir ){ |
| 11783 | /* For a directory, check that the last character in the path is a |
| @@ -12135,10 +11835,17 @@ | |
| 12135 | if( zName==0 ){ |
| 12136 | zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL"); |
| 12137 | rc = SQLITE_ERROR; |
| 12138 | goto zipfile_step_out; |
| 12139 | } |
| 12140 | |
| 12141 | /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use |
| 12142 | ** deflate compression) or NULL (choose automatically). */ |
| 12143 | if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ |
| 12144 | iMethod = (int)sqlite3_value_int64(pMethod); |
| @@ -12477,10 +12184,11 @@ | |
| 12477 | return rc; |
| 12478 | } |
| 12479 | |
| 12480 | /************************* End ../ext/misc/sqlar.c ********************/ |
| 12481 | #endif |
| 12482 | /************************* Begin ../ext/expert/sqlite3expert.h ******************/ |
| 12483 | /* |
| 12484 | ** 2017 April 07 |
| 12485 | ** |
| 12486 | ** The author disclaims copyright to this source code. In place of |
| @@ -14885,10 +14593,11 @@ | |
| 14885 | } |
| 14886 | |
| 14887 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
| 14888 | |
| 14889 | /************************* End ../ext/expert/sqlite3expert.c ********************/ |
| 14890 | /************************* Begin ../ext/intck/sqlite3intck.h ******************/ |
| 14891 | /* |
| 14892 | ** 2024-02-08 |
| 14893 | ** |
| 14894 | ** The author disclaims copyright to this source code. In place of |
| @@ -21525,15 +21234,17 @@ | |
| 21525 | char **azFilter; /* Array of xFilter rejection GLOB patterns */ |
| 21526 | sqlite3_session *p; /* The open session */ |
| 21527 | }; |
| 21528 | #endif |
| 21529 | |
| 21530 | typedef struct ExpertInfo ExpertInfo; |
| 21531 | struct ExpertInfo { |
| 21532 | sqlite3expert *pExpert; |
| 21533 | int bVerbose; |
| 21534 | }; |
| 21535 | |
| 21536 | /* A single line in the EQP output */ |
| 21537 | typedef struct EQPGraphRow EQPGraphRow; |
| 21538 | struct EQPGraphRow { |
| 21539 | int iEqpId; /* ID for this row */ |
| @@ -21633,11 +21344,13 @@ | |
| 21633 | int *aiIndent; /* Array of indents used in MODE_Explain */ |
| 21634 | int nIndent; /* Size of array aiIndent[] */ |
| 21635 | int iIndent; /* Index of current op in aiIndent[] */ |
| 21636 | char *zNonce; /* Nonce for temporary safe-mode escapes */ |
| 21637 | EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ |
| 21638 | ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ |
| 21639 | #ifdef SQLITE_SHELL_FIDDLE |
| 21640 | struct { |
| 21641 | const char * zInput; /* Input string from wasm/JS proxy */ |
| 21642 | const char * zPos; /* Cursor pos into zInput */ |
| 21643 | const char * zDefaultDbName; /* Default name for db file */ |
| @@ -21661,13 +21374,12 @@ | |
| 21661 | */ |
| 21662 | #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ |
| 21663 | #define SHELL_OPEN_NORMAL 1 /* Normal database file */ |
| 21664 | #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ |
| 21665 | #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ |
| 21666 | #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ |
| 21667 | #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ |
| 21668 | #define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */ |
| 21669 | |
| 21670 | /* Allowed values for ShellState.eTraceType |
| 21671 | */ |
| 21672 | #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ |
| 21673 | #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ |
| @@ -22006,11 +21718,11 @@ | |
| 22006 | */ |
| 22007 | static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ |
| 22008 | int i; |
| 22009 | unsigned char *aBlob = (unsigned char*)pBlob; |
| 22010 | |
| 22011 | char *zStr = sqlite3_malloc(nBlob*2 + 1); |
| 22012 | shell_check_oom(zStr); |
| 22013 | |
| 22014 | for(i=0; i<nBlob; i++){ |
| 22015 | static const char aHex[] = { |
| 22016 | '0', '1', '2', '3', '4', '5', '6', '7', |
| @@ -22027,11 +21739,11 @@ | |
| 22027 | |
| 22028 | /* |
| 22029 | ** Output the given string as a quoted string using SQL quoting conventions: |
| 22030 | ** |
| 22031 | ** (1) Single quotes (') within the string are doubled |
| 22032 | ** (2) The whle string is enclosed in '...' |
| 22033 | ** (3) Control characters other than \n, \t, and \r\n are escaped |
| 22034 | ** using \u00XX notation and if such substitutions occur, |
| 22035 | ** the whole string is enclosed in unistr('...') instead of '...'. |
| 22036 | ** |
| 22037 | ** Step (3) is omitted if the control-character escape mode is OFF. |
| @@ -22273,11 +21985,11 @@ | |
| 22273 | ** |
| 22274 | ** Escaping is needed if the string contains any control characters |
| 22275 | ** other than \t, \n, and \r\n |
| 22276 | ** |
| 22277 | ** If no escaping is needed (the common case) then set *ppFree to NULL |
| 22278 | ** and return the original string. If escapingn is needed, write the |
| 22279 | ** escaped string into memory obtained from sqlite3_malloc64() or the |
| 22280 | ** equivalent, and return the new string and set *ppFree to the new string |
| 22281 | ** as well. |
| 22282 | ** |
| 22283 | ** The caller is responsible for freeing *ppFree if it is non-NULL in order |
| @@ -23278,32 +22990,21 @@ | |
| 23278 | ** Set the destination table field of the ShellState structure to |
| 23279 | ** the name of the table given. Escape any quote characters in the |
| 23280 | ** table name. |
| 23281 | */ |
| 23282 | static void set_table_name(ShellState *p, const char *zName){ |
| 23283 | int i, n; |
| 23284 | char cQuote; |
| 23285 | char *z; |
| 23286 | |
| 23287 | if( p->zDestTable ){ |
| 23288 | free(p->zDestTable); |
| 23289 | p->zDestTable = 0; |
| 23290 | } |
| 23291 | if( zName==0 ) return; |
| 23292 | cQuote = quoteChar(zName); |
| 23293 | n = strlen30(zName); |
| 23294 | if( cQuote ) n += n+2; |
| 23295 | z = p->zDestTable = malloc( n+1 ); |
| 23296 | shell_check_oom(z); |
| 23297 | n = 0; |
| 23298 | if( cQuote ) z[n++] = cQuote; |
| 23299 | for(i=0; zName[i]; i++){ |
| 23300 | z[n++] = zName[i]; |
| 23301 | if( zName[i]==cQuote ) z[n++] = cQuote; |
| 23302 | } |
| 23303 | if( cQuote ) z[n++] = cQuote; |
| 23304 | z[n] = 0; |
| 23305 | } |
| 23306 | |
| 23307 | /* |
| 23308 | ** Maybe construct two lines of text that point out the position of a |
| 23309 | ** syntax error. Return a pointer to the text, in memory obtained from |
| @@ -23496,12 +23197,12 @@ | |
| 23496 | static int display_stats( |
| 23497 | sqlite3 *db, /* Database to query */ |
| 23498 | ShellState *pArg, /* Pointer to ShellState */ |
| 23499 | int bReset /* True to reset the stats */ |
| 23500 | ){ |
| 23501 | int iCur; |
| 23502 | int iHiwtr; |
| 23503 | FILE *out; |
| 23504 | if( pArg==0 || pArg->out==0 ) return 0; |
| 23505 | out = pArg->out; |
| 23506 | |
| 23507 | if( pArg->pStmt && pArg->statsOn==2 ){ |
| @@ -23586,18 +23287,25 @@ | |
| 23586 | "Page cache hits: %d\n", iCur); |
| 23587 | iHiwtr = iCur = -1; |
| 23588 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); |
| 23589 | sqlite3_fprintf(out, |
| 23590 | "Page cache misses: %d\n", iCur); |
| 23591 | iHiwtr = iCur = -1; |
| 23592 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); |
| 23593 | sqlite3_fprintf(out, |
| 23594 | "Page cache writes: %d\n", iCur); |
| 23595 | iHiwtr = iCur = -1; |
| 23596 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); |
| 23597 | sqlite3_fprintf(out, |
| 23598 | "Page cache spills: %d\n", iCur); |
| 23599 | iHiwtr = iCur = -1; |
| 23600 | sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); |
| 23601 | sqlite3_fprintf(out, |
| 23602 | "Schema Heap Usage: %d bytes\n", iCur); |
| 23603 | iHiwtr = iCur = -1; |
| @@ -23999,10 +23707,40 @@ | |
| 23999 | char *zBuf = sqlite3_malloc64( szVar-5 ); |
| 24000 | if( zBuf ){ |
| 24001 | memcpy(zBuf, &zVar[6], szVar-5); |
| 24002 | sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8); |
| 24003 | } |
| 24004 | }else{ |
| 24005 | sqlite3_bind_null(pStmt, i); |
| 24006 | } |
| 24007 | sqlite3_reset(pQ); |
| 24008 | } |
| @@ -24581,11 +24319,11 @@ | |
| 24581 | } |
| 24582 | } |
| 24583 | } |
| 24584 | } |
| 24585 | |
| 24586 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 24587 | /* |
| 24588 | ** This function is called to process SQL if the previous shell command |
| 24589 | ** was ".expert". It passes the SQL in the second argument directly to |
| 24590 | ** the sqlite3expert object. |
| 24591 | ** |
| @@ -24713,11 +24451,11 @@ | |
| 24713 | } |
| 24714 | sqlite3_free(zErr); |
| 24715 | |
| 24716 | return rc; |
| 24717 | } |
| 24718 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
| 24719 | |
| 24720 | /* |
| 24721 | ** Execute a statement or set of statements. Print |
| 24722 | ** any result rows/columns depending on the current mode |
| 24723 | ** set via the supplied callback. |
| @@ -24739,11 +24477,11 @@ | |
| 24739 | |
| 24740 | if( pzErrMsg ){ |
| 24741 | *pzErrMsg = NULL; |
| 24742 | } |
| 24743 | |
| 24744 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 24745 | if( pArg->expert.pExpert ){ |
| 24746 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
| 24747 | return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); |
| 24748 | } |
| 24749 | #endif |
| @@ -24901,11 +24639,11 @@ | |
| 24901 | static char **tableColumnList(ShellState *p, const char *zTab){ |
| 24902 | char **azCol = 0; |
| 24903 | sqlite3_stmt *pStmt; |
| 24904 | char *zSql; |
| 24905 | int nCol = 0; |
| 24906 | int nAlloc = 0; |
| 24907 | int nPK = 0; /* Number of PRIMARY KEY columns seen */ |
| 24908 | int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ |
| 24909 | int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); |
| 24910 | int rc; |
| 24911 | |
| @@ -24915,11 +24653,11 @@ | |
| 24915 | sqlite3_free(zSql); |
| 24916 | if( rc ) return 0; |
| 24917 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 24918 | if( nCol>=nAlloc-2 ){ |
| 24919 | nAlloc = nAlloc*2 + nCol + 10; |
| 24920 | azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); |
| 24921 | shell_check_oom(azCol); |
| 24922 | } |
| 24923 | azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); |
| 24924 | shell_check_oom(azCol[nCol]); |
| 24925 | if( sqlite3_column_int(pStmt, 5) ){ |
| @@ -25106,17 +24844,17 @@ | |
| 25106 | appendText(&sSelect, " FROM ", 0); |
| 25107 | appendText(&sSelect, zTable, quoteChar(zTable)); |
| 25108 | |
| 25109 | savedDestTable = p->zDestTable; |
| 25110 | savedMode = p->mode; |
| 25111 | p->zDestTable = sTable.z; |
| 25112 | p->mode = p->cMode = MODE_Insert; |
| 25113 | rc = shell_exec(p, sSelect.z, 0); |
| 25114 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
| 25115 | sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); |
| 25116 | toggleSelectOrder(p->db); |
| 25117 | shell_exec(p, sSelect.z, 0); |
| 25118 | toggleSelectOrder(p->db); |
| 25119 | } |
| 25120 | p->zDestTable = savedDestTable; |
| 25121 | p->mode = savedMode; |
| 25122 | freeText(&sTable); |
| @@ -25245,11 +24983,13 @@ | |
| 25245 | " --bom Put a UTF8 byte-order mark on intermediate file", |
| 25246 | #endif |
| 25247 | #ifndef SQLITE_SHELL_FIDDLE |
| 25248 | ".exit ?CODE? Exit this program with return-code CODE", |
| 25249 | #endif |
| 25250 | ".expert EXPERIMENTAL. Suggest indexes for queries", |
| 25251 | ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto", |
| 25252 | ".filectrl CMD ... Run various sqlite3_file_control() operations", |
| 25253 | " --schema SCHEMA Use SCHEMA instead of \"main\"", |
| 25254 | " --help Show CMD details", |
| 25255 | ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", |
| @@ -25270,11 +25010,11 @@ | |
| 25270 | " from the \".mode\" output mode", |
| 25271 | " * If FILE begins with \"|\" then it is a command that generates the", |
| 25272 | " input text.", |
| 25273 | #endif |
| 25274 | #ifndef SQLITE_OMIT_TEST_CONTROL |
| 25275 | ",imposter INDEX TABLE Create imposter table TABLE on index INDEX", |
| 25276 | #endif |
| 25277 | ".indexes ?TABLE? Show names of indexes", |
| 25278 | " If TABLE is specified, only show indexes for", |
| 25279 | " tables matching TABLE using the LIKE operator.", |
| 25280 | ".intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db", |
| @@ -25337,11 +25077,17 @@ | |
| 25337 | " Options:", |
| 25338 | " --append Use appendvfs to append database to the end of FILE", |
| 25339 | #endif |
| 25340 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 25341 | " --deserialize Load into memory using sqlite3_deserialize()", |
| 25342 | " --hexdb Load the output of \"dbtotxt\" as an in-memory db", |
| 25343 | " --maxsize N Maximum size for --hexdb or --deserialized database", |
| 25344 | #endif |
| 25345 | " --new Initialize FILE to an empty database", |
| 25346 | " --nofollow Do not follow symbolic links", |
| 25347 | " --readonly Open FILE readonly", |
| @@ -25726,14 +25472,14 @@ | |
| 25726 | ** If p->aAuxDb[].zDbFilename is 0, then read from standard input. |
| 25727 | */ |
| 25728 | static unsigned char *readHexDb(ShellState *p, int *pnData){ |
| 25729 | unsigned char *a = 0; |
| 25730 | int nLine; |
| 25731 | int n = 0; |
| 25732 | int pgsz = 0; |
| 25733 | int iOffset = 0; |
| 25734 | int j, k; |
| 25735 | int rc; |
| 25736 | FILE *in; |
| 25737 | const char *zDbFilename = p->pAuxDb->zDbFilename; |
| 25738 | unsigned int x[16]; |
| 25739 | char zLine[1000]; |
| @@ -25753,20 +25499,21 @@ | |
| 25753 | nLine++; |
| 25754 | if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; |
| 25755 | rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); |
| 25756 | if( rc!=2 ) goto readHexDb_error; |
| 25757 | if( n<0 ) goto readHexDb_error; |
| 25758 | if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; |
| 25759 | n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ |
| 25760 | a = sqlite3_malloc( n ? n : 1 ); |
| 25761 | shell_check_oom(a); |
| 25762 | memset(a, 0, n); |
| 25763 | if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
| 25764 | sqlite3_fputs("invalid pagesize\n", stderr); |
| 25765 | goto readHexDb_error; |
| 25766 | } |
| 25767 | for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
| 25768 | rc = sscanf(zLine, "| page %d offset %d", &j, &k); |
| 25769 | if( rc==2 ){ |
| 25770 | iOffset = k; |
| 25771 | continue; |
| 25772 | } |
| @@ -25775,18 +25522,18 @@ | |
| 25775 | } |
| 25776 | rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", |
| 25777 | &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], |
| 25778 | &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); |
| 25779 | if( rc==17 ){ |
| 25780 | k = iOffset+j; |
| 25781 | if( k+16<=n && k>=0 ){ |
| 25782 | int ii; |
| 25783 | for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff; |
| 25784 | } |
| 25785 | } |
| 25786 | } |
| 25787 | *pnData = n; |
| 25788 | if( in!=p->in ){ |
| 25789 | fclose(in); |
| 25790 | }else{ |
| 25791 | p->lineno = nLine; |
| 25792 | } |
| @@ -25849,11 +25596,11 @@ | |
| 25849 | p->pLog = pSavedLog; |
| 25850 | |
| 25851 | if( zFake ){ |
| 25852 | sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), |
| 25853 | -1, sqlite3_free); |
| 25854 | free(zFake); |
| 25855 | } |
| 25856 | } |
| 25857 | |
| 25858 | /* Flags for open_db(). |
| 25859 | ** |
| @@ -25881,14 +25628,17 @@ | |
| 25881 | }else{ |
| 25882 | p->openMode = (u8)deduceDatabaseType(zDbFilename, |
| 25883 | (openFlags & OPEN_DB_ZIPFILE)!=0); |
| 25884 | } |
| 25885 | } |
| 25886 | switch( p->openMode ){ |
| 25887 | case SHELL_OPEN_APPENDVFS: { |
| 25888 | sqlite3_open_v2(zDbFilename, &p->db, |
| 25889 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs"); |
| 25890 | break; |
| 25891 | } |
| 25892 | case SHELL_OPEN_HEXDB: |
| 25893 | case SHELL_OPEN_DESERIALIZE: { |
| 25894 | sqlite3_open(0, &p->db); |
| @@ -25896,19 +25646,13 @@ | |
| 25896 | } |
| 25897 | case SHELL_OPEN_ZIPFILE: { |
| 25898 | sqlite3_open(":memory:", &p->db); |
| 25899 | break; |
| 25900 | } |
| 25901 | case SHELL_OPEN_READONLY: { |
| 25902 | sqlite3_open_v2(zDbFilename, &p->db, |
| 25903 | SQLITE_OPEN_READONLY|p->openFlags, 0); |
| 25904 | break; |
| 25905 | } |
| 25906 | case SHELL_OPEN_UNSPEC: |
| 25907 | case SHELL_OPEN_NORMAL: { |
| 25908 | sqlite3_open_v2(zDbFilename, &p->db, |
| 25909 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); |
| 25910 | break; |
| 25911 | } |
| 25912 | } |
| 25913 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
| 25914 | sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
| @@ -25944,11 +25688,10 @@ | |
| 25944 | sqlite3_sha_init(p->db, 0, 0); |
| 25945 | sqlite3_shathree_init(p->db, 0, 0); |
| 25946 | sqlite3_uint_init(p->db, 0, 0); |
| 25947 | sqlite3_stmtrand_init(p->db, 0, 0); |
| 25948 | sqlite3_decimal_init(p->db, 0, 0); |
| 25949 | sqlite3_percentile_init(p->db, 0, 0); |
| 25950 | sqlite3_base64_init(p->db, 0, 0); |
| 25951 | sqlite3_base85_init(p->db, 0, 0); |
| 25952 | sqlite3_regexp_init(p->db, 0, 0); |
| 25953 | sqlite3_ieee_init(p->db, 0, 0); |
| 25954 | sqlite3_series_init(p->db, 0, 0); |
| @@ -26043,13 +25786,15 @@ | |
| 26043 | } |
| 26044 | } |
| 26045 | #endif |
| 26046 | } |
| 26047 | if( p->db!=0 ){ |
| 26048 | if( p->bSafeModePersist ){ |
| 26049 | sqlite3_set_authorizer(p->db, safeModeAuth, p); |
| 26050 | } |
| 26051 | sqlite3_db_config( |
| 26052 | p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0 |
| 26053 | ); |
| 26054 | } |
| 26055 | } |
| @@ -26358,12 +26103,12 @@ | |
| 26358 | struct ImportCtx { |
| 26359 | const char *zFile; /* Name of the input file */ |
| 26360 | FILE *in; /* Read the CSV text from this input stream */ |
| 26361 | int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */ |
| 26362 | char *z; /* Accumulated text for a field */ |
| 26363 | int n; /* Number of bytes in z */ |
| 26364 | int nAlloc; /* Space allocated for z[] */ |
| 26365 | int nLine; /* Current line number */ |
| 26366 | int nRow; /* Number of rows imported */ |
| 26367 | int nErr; /* Number of errors encountered */ |
| 26368 | int bNotFirst; /* True if one or more bytes already read */ |
| 26369 | int cTerm; /* Character that terminated the most recent field */ |
| @@ -26829,14 +26574,17 @@ | |
| 26829 | #if SQLITE_SHELL_HAVE_RECOVER |
| 26830 | /* |
| 26831 | ** Convert a 2-byte or 4-byte big-endian integer into a native integer |
| 26832 | */ |
| 26833 | static unsigned int get2byteInt(unsigned char *a){ |
| 26834 | return (a[0]<<8) + a[1]; |
| 26835 | } |
| 26836 | static unsigned int get4byteInt(unsigned char *a){ |
| 26837 | return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; |
| 26838 | } |
| 26839 | |
| 26840 | /* |
| 26841 | ** Implementation of the ".dbinfo" command. |
| 26842 | ** |
| @@ -26969,11 +26717,11 @@ | |
| 26969 | if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; |
| 26970 | nPage = sqlite3_column_int64(pStmt, 0); |
| 26971 | sqlite3_finalize(pStmt); |
| 26972 | pStmt = 0; |
| 26973 | if( nPage<1 ) goto dbtotxt_error; |
| 26974 | rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0); |
| 26975 | if( rc ) goto dbtotxt_error; |
| 26976 | if( sqlite3_step(pStmt)!=SQLITE_ROW ){ |
| 26977 | zTail = "unk.db"; |
| 26978 | }else{ |
| 26979 | const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2); |
| @@ -26980,10 +26728,15 @@ | |
| 26980 | if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; |
| 26981 | zTail = strrchr(zFilename, '/'); |
| 26982 | #if defined(_WIN32) |
| 26983 | if( zTail==0 ) zTail = strrchr(zFilename, '\\'); |
| 26984 | #endif |
| 26985 | } |
| 26986 | zName = strdup(zTail); |
| 26987 | shell_check_oom(zName); |
| 26988 | sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", |
| 26989 | nPage*pgSz, pgSz, zName); |
| @@ -27148,10 +26901,47 @@ | |
| 27148 | if( zStr[0]!='-' ) return 0; |
| 27149 | zStr++; |
| 27150 | if( zStr[0]=='-' ) zStr++; |
| 27151 | return cli_strcmp(zStr, zOpt)==0; |
| 27152 | } |
| 27153 | |
| 27154 | /* |
| 27155 | ** Delete a file. |
| 27156 | */ |
| 27157 | int shellDeleteFile(const char *zFilename){ |
| @@ -28704,11 +28494,11 @@ | |
| 28704 | int nArg = 0; |
| 28705 | int n, c; |
| 28706 | int rc = 0; |
| 28707 | char *azArg[52]; |
| 28708 | |
| 28709 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 28710 | if( p->expert.pExpert ){ |
| 28711 | expertFinish(p, 1, 0); |
| 28712 | } |
| 28713 | #endif |
| 28714 | |
| @@ -29005,11 +28795,11 @@ | |
| 29005 | }else{ |
| 29006 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 29007 | const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); |
| 29008 | const char *zFile = (const char*)sqlite3_column_text(pStmt,2); |
| 29009 | if( zSchema==0 || zFile==0 ) continue; |
| 29010 | azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*)); |
| 29011 | shell_check_oom(azName); |
| 29012 | azName[nName*2] = strdup(zSchema); |
| 29013 | azName[nName*2+1] = strdup(zFile); |
| 29014 | nName++; |
| 29015 | } |
| @@ -29208,10 +28998,11 @@ | |
| 29208 | rc = 1; |
| 29209 | } |
| 29210 | }else |
| 29211 | |
| 29212 | if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ |
| 29213 | rc = shell_dbtotxt_command(p, nArg, azArg); |
| 29214 | }else |
| 29215 | |
| 29216 | if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ |
| 29217 | if( nArg==2 ){ |
| @@ -29273,11 +29064,11 @@ | |
| 29273 | if( p->mode==MODE_Explain ) p->mode = p->normalMode; |
| 29274 | p->autoExplain = 1; |
| 29275 | } |
| 29276 | }else |
| 29277 | |
| 29278 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 29279 | if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ |
| 29280 | if( p->bSafeMode ){ |
| 29281 | sqlite3_fprintf(stderr, |
| 29282 | "Cannot run experimental commands such as \"%s\" in safe mode\n", |
| 29283 | azArg[0]); |
| @@ -29840,16 +29631,10 @@ | |
| 29840 | sqlite3_stmt *pStmt; |
| 29841 | int tnum = 0; |
| 29842 | int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ |
| 29843 | int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ |
| 29844 | int i; |
| 29845 | if( !ShellHasFlag(p,SHFLG_TestingMode) ){ |
| 29846 | sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n", |
| 29847 | "imposter"); |
| 29848 | rc = 1; |
| 29849 | goto meta_command_exit; |
| 29850 | } |
| 29851 | if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ |
| 29852 | eputz("Usage: .imposter INDEX IMPOSTER\n" |
| 29853 | " .imposter off\n"); |
| 29854 | /* Also allowed, but not documented: |
| 29855 | ** |
| @@ -29917,22 +29702,19 @@ | |
| 29917 | if( lenPK==0 ) lenPK = 100000; |
| 29918 | zSql = sqlite3_mprintf( |
| 29919 | "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID", |
| 29920 | azArg[2], zCollist, lenPK, zCollist); |
| 29921 | sqlite3_free(zCollist); |
| 29922 | rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); |
| 29923 | if( rc==SQLITE_OK ){ |
| 29924 | rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
| 29925 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); |
| 29926 | if( rc ){ |
| 29927 | sqlite3_fprintf(stderr, |
| 29928 | "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); |
| 29929 | }else{ |
| 29930 | sqlite3_fprintf(stdout, "%s;\n", zSql); |
| 29931 | sqlite3_fprintf(stdout, |
| 29932 | "WARNING: writing to an imposter table will corrupt" |
| 29933 | " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); |
| 29934 | } |
| 29935 | }else{ |
| 29936 | sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); |
| 29937 | rc = 1; |
| 29938 | } |
| @@ -30282,10 +30064,11 @@ | |
| 30282 | const char *zFN = 0; /* Pointer to constant filename */ |
| 30283 | char *zNewFilename = 0; /* Name of the database file to open */ |
| 30284 | int iName = 1; /* Index in azArg[] of the filename */ |
| 30285 | int newFlag = 0; /* True to delete file before opening */ |
| 30286 | int openMode = SHELL_OPEN_UNSPEC; |
| 30287 | |
| 30288 | /* Check for command-line arguments */ |
| 30289 | for(iName=1; iName<nArg; iName++){ |
| 30290 | const char *z = azArg[iName]; |
| 30291 | #ifndef SQLITE_SHELL_FIDDLE |
| @@ -30296,13 +30079,18 @@ | |
| 30296 | openMode = SHELL_OPEN_ZIPFILE; |
| 30297 | #endif |
| 30298 | }else if( optionMatch(z, "append") ){ |
| 30299 | openMode = SHELL_OPEN_APPENDVFS; |
| 30300 | }else if( optionMatch(z, "readonly") ){ |
| 30301 | openMode = SHELL_OPEN_READONLY; |
| 30302 | }else if( optionMatch(z, "nofollow") ){ |
| 30303 | p->openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 30304 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 30305 | }else if( optionMatch(z, "deserialize") ){ |
| 30306 | openMode = SHELL_OPEN_DESERIALIZE; |
| 30307 | }else if( optionMatch(z, "hexdb") ){ |
| 30308 | openMode = SHELL_OPEN_HEXDB; |
| @@ -30330,16 +30118,25 @@ | |
| 30330 | p->db = 0; |
| 30331 | p->pAuxDb->zDbFilename = 0; |
| 30332 | sqlite3_free(p->pAuxDb->zFreeOnClose); |
| 30333 | p->pAuxDb->zFreeOnClose = 0; |
| 30334 | p->openMode = openMode; |
| 30335 | p->openFlags = 0; |
| 30336 | p->szMax = 0; |
| 30337 | |
| 30338 | /* If a filename is specified, try to open it first */ |
| 30339 | if( zFN || p->openMode==SHELL_OPEN_HEXDB ){ |
| 30340 | if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN); |
| 30341 | #ifndef SQLITE_SHELL_FIDDLE |
| 30342 | if( p->bSafeMode |
| 30343 | && p->openMode!=SHELL_OPEN_HEXDB |
| 30344 | && zFN |
| 30345 | && cli_strcmp(zFN,":memory:")!=0 |
| @@ -30938,13 +30735,13 @@ | |
| 30938 | appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0); |
| 30939 | } |
| 30940 | appendText(&sSelect, "sql IS NOT NULL" |
| 30941 | " ORDER BY snum, rowid", 0); |
| 30942 | if( bDebug ){ |
| 30943 | sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z); |
| 30944 | }else{ |
| 30945 | rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); |
| 30946 | } |
| 30947 | freeText(&sSelect); |
| 30948 | } |
| 30949 | if( zErrMsg ){ |
| 30950 | shellEmitError(zErrMsg); |
| @@ -31072,19 +30869,20 @@ | |
| 31072 | |
| 31073 | /* .session filter GLOB .... |
| 31074 | ** Set a list of GLOB patterns of table names to be excluded. |
| 31075 | */ |
| 31076 | if( cli_strcmp(azCmd[0], "filter")==0 ){ |
| 31077 | int ii, nByte; |
| 31078 | if( nCmd<2 ) goto session_syntax_error; |
| 31079 | if( pAuxDb->nSession ){ |
| 31080 | for(ii=0; ii<pSession->nFilter; ii++){ |
| 31081 | sqlite3_free(pSession->azFilter[ii]); |
| 31082 | } |
| 31083 | sqlite3_free(pSession->azFilter); |
| 31084 | nByte = sizeof(pSession->azFilter[0])*(nCmd-1); |
| 31085 | pSession->azFilter = sqlite3_malloc( nByte ); |
| 31086 | shell_check_oom( pSession->azFilter ); |
| 31087 | for(ii=1; ii<nCmd; ii++){ |
| 31088 | char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); |
| 31089 | shell_check_oom(x); |
| 31090 | } |
| @@ -31264,26 +31062,26 @@ | |
| 31264 | sqlite3_fprintf(p->out, "%s\n", zSql); |
| 31265 | }else |
| 31266 | if( cli_strcmp(zOp,"run")==0 ){ |
| 31267 | char *zErrMsg = 0; |
| 31268 | str.n = 0; |
| 31269 | str.z[0] = 0; |
| 31270 | rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); |
| 31271 | nTest++; |
| 31272 | if( bVerbose ){ |
| 31273 | sqlite3_fprintf(p->out, "Result: %s\n", str.z); |
| 31274 | } |
| 31275 | if( rc || zErrMsg ){ |
| 31276 | nErr++; |
| 31277 | rc = 1; |
| 31278 | sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); |
| 31279 | sqlite3_free(zErrMsg); |
| 31280 | }else if( cli_strcmp(zAns,str.z)!=0 ){ |
| 31281 | nErr++; |
| 31282 | rc = 1; |
| 31283 | sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); |
| 31284 | sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z); |
| 31285 | } |
| 31286 | } |
| 31287 | else{ |
| 31288 | sqlite3_fprintf(stderr, |
| 31289 | "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); |
| @@ -31395,11 +31193,11 @@ | |
| 31395 | appendText(&sQuery, "SELECT * FROM ", 0); |
| 31396 | appendText(&sQuery, zTab, 0); |
| 31397 | appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); |
| 31398 | } |
| 31399 | appendText(&sSql, zSep, 0); |
| 31400 | appendText(&sSql, sQuery.z, '\''); |
| 31401 | sQuery.n = 0; |
| 31402 | appendText(&sSql, ",", 0); |
| 31403 | appendText(&sSql, zTab, '\''); |
| 31404 | zSep = "),("; |
| 31405 | } |
| @@ -31407,17 +31205,17 @@ | |
| 31407 | if( bSeparate ){ |
| 31408 | zSql = sqlite3_mprintf( |
| 31409 | "%s))" |
| 31410 | " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" |
| 31411 | " FROM [sha3sum$query]", |
| 31412 | sSql.z, iSize); |
| 31413 | }else{ |
| 31414 | zSql = sqlite3_mprintf( |
| 31415 | "%s))" |
| 31416 | " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" |
| 31417 | " FROM [sha3sum$query]", |
| 31418 | sSql.z, iSize); |
| 31419 | } |
| 31420 | shell_check_oom(zSql); |
| 31421 | freeText(&sQuery); |
| 31422 | freeText(&sSql); |
| 31423 | if( bDebug ){ |
| @@ -31613,11 +31411,11 @@ | |
| 31613 | goto meta_command_exit; |
| 31614 | } |
| 31615 | for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ |
| 31616 | const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); |
| 31617 | if( zDbName==0 ) continue; |
| 31618 | if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0); |
| 31619 | if( sqlite3_stricmp(zDbName, "main")==0 ){ |
| 31620 | appendText(&s, "SELECT name FROM ", 0); |
| 31621 | }else{ |
| 31622 | appendText(&s, "SELECT ", 0); |
| 31623 | appendText(&s, zDbName, '\''); |
| @@ -31635,11 +31433,11 @@ | |
| 31635 | } |
| 31636 | } |
| 31637 | rc = sqlite3_finalize(pStmt); |
| 31638 | if( rc==SQLITE_OK ){ |
| 31639 | appendText(&s, " ORDER BY 1", 0); |
| 31640 | rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0); |
| 31641 | } |
| 31642 | freeText(&s); |
| 31643 | if( rc ) return shellDatabaseError(p->db); |
| 31644 | |
| 31645 | /* Run the SQL statement prepared by the above block. Store the results |
| @@ -31652,14 +31450,14 @@ | |
| 31652 | sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); |
| 31653 | } |
| 31654 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 31655 | if( nRow>=nAlloc ){ |
| 31656 | char **azNew; |
| 31657 | int n2 = nAlloc*2 + 10; |
| 31658 | azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); |
| 31659 | shell_check_oom(azNew); |
| 31660 | nAlloc = n2; |
| 31661 | azResult = azNew; |
| 31662 | } |
| 31663 | azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); |
| 31664 | shell_check_oom(azResult[nRow]); |
| 31665 | nRow++; |
| @@ -31818,11 +31616,11 @@ | |
| 31818 | { 0x00000020, 1, "CoverIdxScan" }, |
| 31819 | { 0x00000040, 1, "OrderByIdxJoin" }, |
| 31820 | { 0x00000080, 1, "Transitive" }, |
| 31821 | { 0x00000100, 1, "OmitNoopJoin" }, |
| 31822 | { 0x00000200, 1, "CountOfView" }, |
| 31823 | { 0x00000400, 1, "CurosrHints" }, |
| 31824 | { 0x00000800, 1, "Stat4" }, |
| 31825 | { 0x00001000, 1, "PushDown" }, |
| 31826 | { 0x00002000, 1, "SimplifyJoin" }, |
| 31827 | { 0x00004000, 1, "SkipScan" }, |
| 31828 | { 0x00008000, 1, "PropagateConst" }, |
| @@ -32365,11 +32163,14 @@ | |
| 32365 | p->nWidth = nArg-1; |
| 32366 | p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2); |
| 32367 | if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory(); |
| 32368 | if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth]; |
| 32369 | for(j=1; j<nArg; j++){ |
| 32370 | p->colWidth[j-1] = (int)integerValue(azArg[j]); |
| 32371 | } |
| 32372 | }else |
| 32373 | |
| 32374 | { |
| 32375 | sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " |
| @@ -32888,76 +32689,95 @@ | |
| 32888 | |
| 32889 | return home_dir; |
| 32890 | } |
| 32891 | |
| 32892 | /* |
| 32893 | ** On non-Windows platforms, look for $XDG_CONFIG_HOME. |
| 32894 | ** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return |
| 32895 | ** the path to it. If there is no $(XDG_CONFIG_HOME) then |
| 32896 | ** look for $(HOME)/.config/sqlite3/sqliterc and if found |
| 32897 | ** return that. If none of these are found, return 0. |
| 32898 | ** |
| 32899 | ** The string returned is obtained from sqlite3_malloc() and |
| 32900 | ** should be freed by the caller. |
| 32901 | */ |
| 32902 | static char *find_xdg_config(void){ |
| 32903 | #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ |
| 32904 | || defined(__RTP__) || defined(_WRS_KERNEL) |
| 32905 | return 0; |
| 32906 | #else |
| 32907 | char *zConfig = 0; |
| 32908 | const char *zXdgHome; |
| 32909 | |
| 32910 | zXdgHome = getenv("XDG_CONFIG_HOME"); |
| 32911 | if( zXdgHome==0 ){ |
| 32912 | const char *zHome = getenv("HOME"); |
| 32913 | if( zHome==0 ) return 0; |
| 32914 | zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome); |
| 32915 | }else{ |
| 32916 | zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); |
| 32917 | } |
| 32918 | shell_check_oom(zConfig); |
| 32919 | if( access(zConfig,0)!=0 ){ |
| 32920 | sqlite3_free(zConfig); |
| 32921 | zConfig = 0; |
| 32922 | } |
| 32923 | return zConfig; |
| 32924 | #endif |
| 32925 | } |
| 32926 | |
| 32927 | /* |
| 32928 | ** Read input from the file given by sqliterc_override. Or if that |
| 32929 | ** parameter is NULL, take input from the first of find_xdg_config() |
| 32930 | ** or ~/.sqliterc which is found. |
| 32931 | ** |
| 32932 | ** Returns the number of errors. |
| 32933 | */ |
| 32934 | static void process_sqliterc( |
| 32935 | ShellState *p, /* Configuration data */ |
| 32936 | const char *sqliterc_override /* Name of config file. NULL to use default */ |
| 32937 | ){ |
| 32938 | char *home_dir = NULL; |
| 32939 | const char *sqliterc = sqliterc_override; |
| 32940 | char *zBuf = 0; |
| 32941 | FILE *inSaved = p->in; |
| 32942 | int savedLineno = p->lineno; |
| 32943 | |
| 32944 | if( sqliterc == NULL ){ |
| 32945 | sqliterc = zBuf = find_xdg_config(); |
| 32946 | } |
| 32947 | if( sqliterc == NULL ){ |
| 32948 | home_dir = find_home_dir(0); |
| 32949 | if( home_dir==0 ){ |
| 32950 | eputz("-- warning: cannot find home directory;" |
| 32951 | " cannot read ~/.sqliterc\n"); |
| 32952 | return; |
| 32953 | } |
| 32954 | zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); |
| 32955 | shell_check_oom(zBuf); |
| 32956 | sqliterc = zBuf; |
| 32957 | } |
| 32958 | p->in = sqlite3_fopen(sqliterc,"rb"); |
| 32959 | if( p->in ){ |
| 32960 | if( stdin_is_interactive ){ |
| 32961 | sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); |
| 32962 | } |
| 32963 | if( process_input(p) && bail_on_error ) exit(1); |
| @@ -32966,11 +32786,13 @@ | |
| 32966 | sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); |
| 32967 | if( bail_on_error ) exit(1); |
| 32968 | } |
| 32969 | p->in = inSaved; |
| 32970 | p->lineno = savedLineno; |
| 32971 | sqlite3_free(zBuf); |
| 32972 | } |
| 32973 | |
| 32974 | /* |
| 32975 | ** Show available command line options |
| 32976 | */ |
| @@ -32997,10 +32819,11 @@ | |
| 32997 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
| 32998 | " -heap SIZE Size of heap for memsys3 or memsys5\n" |
| 32999 | #endif |
| 33000 | " -help show this message\n" |
| 33001 | " -html set output mode to HTML\n" |
| 33002 | " -interactive force interactive I/O\n" |
| 33003 | " -json set output mode to 'json'\n" |
| 33004 | " -line set output mode to 'line'\n" |
| 33005 | " -list set output mode to 'list'\n" |
| 33006 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| @@ -33341,16 +33164,24 @@ | |
| 33341 | (void)cmdline_option_value(argc, argv, ++i); |
| 33342 | #endif |
| 33343 | }else if( cli_strcmp(z,"-pagecache")==0 ){ |
| 33344 | sqlite3_int64 n, sz; |
| 33345 | sz = integerValue(cmdline_option_value(argc,argv,++i)); |
| 33346 | if( sz>70000 ) sz = 70000; |
| 33347 | if( sz<0 ) sz = 0; |
| 33348 | n = integerValue(cmdline_option_value(argc,argv,++i)); |
| 33349 | if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){ |
| 33350 | n = 0xffffffffffffLL/sz; |
| 33351 | } |
| 33352 | verify_uninitialized(); |
| 33353 | sqlite3_config(SQLITE_CONFIG_PAGECACHE, |
| 33354 | (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); |
| 33355 | data.shellFlgs |= SHFLG_Pagecache; |
| 33356 | }else if( cli_strcmp(z,"-lookaside")==0 ){ |
| @@ -33359,11 +33190,11 @@ | |
| 33359 | if( sz<0 ) sz = 0; |
| 33360 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
| 33361 | if( n<0 ) n = 0; |
| 33362 | verify_uninitialized(); |
| 33363 | sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); |
| 33364 | if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; |
| 33365 | }else if( cli_strcmp(z,"-threadsafe")==0 ){ |
| 33366 | int n; |
| 33367 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
| 33368 | verify_uninitialized(); |
| 33369 | switch( n ){ |
| @@ -33401,13 +33232,19 @@ | |
| 33401 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33402 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33403 | data.szMax = integerValue(argv[++i]); |
| 33404 | #endif |
| 33405 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33406 | data.openMode = SHELL_OPEN_READONLY; |
| 33407 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33408 | data.openFlags = SQLITE_OPEN_NOFOLLOW; |
| 33409 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
| 33410 | }else if( cli_strncmp(z, "-A",2)==0 ){ |
| 33411 | /* All remaining command-line arguments are passed to the ".archive" |
| 33412 | ** command, so ignore them */ |
| 33413 | break; |
| @@ -33557,13 +33394,19 @@ | |
| 33557 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33558 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33559 | data.szMax = integerValue(argv[++i]); |
| 33560 | #endif |
| 33561 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33562 | data.openMode = SHELL_OPEN_READONLY; |
| 33563 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33564 | data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 33565 | }else if( cli_strcmp(z,"-ascii")==0 ){ |
| 33566 | data.mode = MODE_Ascii; |
| 33567 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit); |
| 33568 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record); |
| 33569 | }else if( cli_strcmp(z,"-tabs")==0 ){ |
| @@ -33734,11 +33577,10 @@ | |
| 33734 | /* Run commands received from standard input |
| 33735 | */ |
| 33736 | if( stdin_is_interactive ){ |
| 33737 | char *zHome; |
| 33738 | char *zHistory; |
| 33739 | int nHistory; |
| 33740 | sqlite3_fprintf(stdout, |
| 33741 | "SQLite version %s %.19s\n" /*extra-version-info*/ |
| 33742 | "Enter \".help\" for usage hints.\n", |
| 33743 | sqlite3_libversion(), sqlite3_sourceid()); |
| 33744 | if( warnInmemoryDb ){ |
| @@ -33747,15 +33589,19 @@ | |
| 33747 | sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a" |
| 33748 | " persistent database.\n"); |
| 33749 | } |
| 33750 | zHistory = getenv("SQLITE_HISTORY"); |
| 33751 | if( zHistory ){ |
| 33752 | zHistory = strdup(zHistory); |
| 33753 | }else if( (zHome = find_home_dir(0))!=0 ){ |
| 33754 | nHistory = strlen30(zHome) + 20; |
| 33755 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 33756 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
| 33757 | } |
| 33758 | } |
| 33759 | if( zHistory ){ shell_read_history(zHistory); } |
| 33760 | #if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) |
| 33761 | rl_attempted_completion_function = readline_completion; |
| @@ -33767,21 +33613,21 @@ | |
| 33767 | data.in = 0; |
| 33768 | rc = process_input(&data); |
| 33769 | if( zHistory ){ |
| 33770 | shell_stifle_history(2000); |
| 33771 | shell_write_history(zHistory); |
| 33772 | free(zHistory); |
| 33773 | } |
| 33774 | }else{ |
| 33775 | data.in = stdin; |
| 33776 | rc = process_input(&data); |
| 33777 | } |
| 33778 | } |
| 33779 | #ifndef SQLITE_SHELL_FIDDLE |
| 33780 | /* In WASM mode we have to leave the db state in place so that |
| 33781 | ** client code can "push" SQL into it after this call returns. */ |
| 33782 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 33783 | if( data.expert.pExpert ){ |
| 33784 | expertFinish(&data, 1, 0); |
| 33785 | } |
| 33786 | #endif |
| 33787 | shell_main_exit: |
| 33788 |
| --- extsrc/shell.c | |
| +++ extsrc/shell.c | |
| @@ -122,10 +122,13 @@ | |
| 122 | typedef sqlite3_int64 i64; |
| 123 | typedef sqlite3_uint64 u64; |
| 124 | typedef unsigned char u8; |
| 125 | #include <ctype.h> |
| 126 | #include <stdarg.h> |
| 127 | #ifndef _WIN32 |
| 128 | # include <sys/time.h> |
| 129 | #endif |
| 130 | |
| 131 | #if !defined(_WIN32) && !defined(WIN32) |
| 132 | # include <signal.h> |
| 133 | # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI) |
| 134 | # include <pwd.h> |
| @@ -646,12 +649,23 @@ | |
| 649 | if( a==0 ) a = ""; |
| 650 | if( b==0 ) b = ""; |
| 651 | return strncmp(a,b,n); |
| 652 | } |
| 653 | |
| 654 | /* Return the current wall-clock time in microseconds since the |
| 655 | ** Unix epoch (1970-01-01T00:00:00Z) |
| 656 | */ |
| 657 | static sqlite3_int64 timeOfDay(void){ |
| 658 | #if defined(_WIN64) |
| 659 | sqlite3_uint64 t; |
| 660 | FILETIME tm; |
| 661 | GetSystemTimePreciseAsFileTime(&tm); |
| 662 | t = ((u64)tm.dwHighDateTime<<32) | (u64)tm.dwLowDateTime; |
| 663 | t += 116444736000000000LL; |
| 664 | t /= 10; |
| 665 | return t; |
| 666 | #elif defined(_WIN32) |
| 667 | static sqlite3_vfs *clockVfs = 0; |
| 668 | sqlite3_int64 t; |
| 669 | if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); |
| 670 | if( clockVfs==0 ) return 0; /* Never actually happens */ |
| 671 | if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ |
| @@ -659,11 +673,16 @@ | |
| 673 | }else{ |
| 674 | double r; |
| 675 | clockVfs->xCurrentTime(clockVfs, &r); |
| 676 | t = (sqlite3_int64)(r*86400000.0); |
| 677 | } |
| 678 | return t*1000; |
| 679 | #else |
| 680 | struct timeval sNow; |
| 681 | (void)gettimeofday(&sNow,0); |
| 682 | return ((i64)sNow.tv_sec)*1000000 + sNow.tv_usec; |
| 683 | #endif |
| 684 | } |
| 685 | |
| 686 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) |
| 687 | #include <sys/time.h> |
| 688 | #include <sys/resource.h> |
| @@ -704,12 +723,12 @@ | |
| 723 | static void endTimer(FILE *out){ |
| 724 | if( enableTimer ){ |
| 725 | sqlite3_int64 iEnd = timeOfDay(); |
| 726 | struct rusage sEnd; |
| 727 | getrusage(RUSAGE_SELF, &sEnd); |
| 728 | sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n", |
| 729 | (iEnd - iBegin)*0.000001, |
| 730 | timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |
| 731 | timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
| 732 | } |
| 733 | } |
| 734 | |
| @@ -783,14 +802,23 @@ | |
| 802 | static void endTimer(FILE *out){ |
| 803 | if( enableTimer && getProcessTimesAddr){ |
| 804 | FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
| 805 | sqlite3_int64 ftWallEnd = timeOfDay(); |
| 806 | getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); |
| 807 | #ifdef _WIN64 |
| 808 | /* microsecond precision on 64-bit windows */ |
| 809 | sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n", |
| 810 | (ftWallEnd - ftWallBegin)*0.000001, |
| 811 | timeDiff(&ftUserBegin, &ftUserEnd), |
| 812 | timeDiff(&ftKernelBegin, &ftKernelEnd)); |
| 813 | #else |
| 814 | /* millisecond precisino on 32-bit windows */ |
| 815 | sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n", |
| 816 | (ftWallEnd - ftWallBegin)*0.000001, |
| 817 | timeDiff(&ftUserBegin, &ftUserEnd), |
| 818 | timeDiff(&ftKernelBegin, &ftKernelEnd)); |
| 819 | #endif |
| 820 | } |
| 821 | } |
| 822 | |
| 823 | #define BEGIN_TIMER beginTimer() |
| 824 | #define END_TIMER(X) endTimer(X) |
| @@ -1126,11 +1154,11 @@ | |
| 1154 | } |
| 1155 | if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 |
| 1156 | && (z[3] & 0xc0)==0x80 |
| 1157 | ){ |
| 1158 | *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 |
| 1159 | | (z[3] & 0x3f); |
| 1160 | return 4; |
| 1161 | } |
| 1162 | *pU = 0; |
| 1163 | return 1; |
| 1164 | } |
| @@ -1189,18 +1217,28 @@ | |
| 1217 | ** since with %*.*s the width is measured in bytes, not characters. |
| 1218 | ** |
| 1219 | ** Take into account zero-width and double-width Unicode characters. |
| 1220 | ** In other words, a zero-width character does not count toward the |
| 1221 | ** the w limit. A double-width character counts as two. |
| 1222 | ** |
| 1223 | ** w should normally be a small number. A couple hundred at most. This |
| 1224 | ** routine caps w at 100 million to avoid integer overflow issues. |
| 1225 | */ |
| 1226 | static void utf8_width_print(FILE *out, int w, const char *zUtf){ |
| 1227 | const unsigned char *a = (const unsigned char*)zUtf; |
| 1228 | static const int mxW = 10000000; |
| 1229 | unsigned char c; |
| 1230 | int i = 0; |
| 1231 | int n = 0; |
| 1232 | int k; |
| 1233 | int aw; |
| 1234 | if( w<-mxW ){ |
| 1235 | w = -mxW; |
| 1236 | }else if( w>mxW ){ |
| 1237 | w= mxW; |
| 1238 | } |
| 1239 | aw = w<0 ? -w : w; |
| 1240 | if( zUtf==0 ) zUtf = ""; |
| 1241 | while( (c = a[i])!=0 ){ |
| 1242 | if( (c&0xc0)==0xc0 ){ |
| 1243 | int u; |
| 1244 | int len = decodeUtf8(a+i, &u); |
| @@ -1323,11 +1361,11 @@ | |
| 1361 | |
| 1362 | /* |
| 1363 | ** This routine reads a line of text from FILE in, stores |
| 1364 | ** the text in memory obtained from malloc() and returns a pointer |
| 1365 | ** to the text. NULL is returned at end of file, or if malloc() |
| 1366 | ** fails, or if the length of the line is longer than about a gigabyte. |
| 1367 | ** |
| 1368 | ** If zLine is not NULL then it is a malloced buffer returned from |
| 1369 | ** a previous call to this routine that may be reused. |
| 1370 | */ |
| 1371 | static char *local_getline(char *zLine, FILE *in){ |
| @@ -1334,10 +1372,14 @@ | |
| 1372 | int nLine = zLine==0 ? 0 : 100; |
| 1373 | int n = 0; |
| 1374 | |
| 1375 | while( 1 ){ |
| 1376 | if( n+100>nLine ){ |
| 1377 | if( nLine>=1073741773 ){ |
| 1378 | free(zLine); |
| 1379 | return 0; |
| 1380 | } |
| 1381 | nLine = nLine*2 + 100; |
| 1382 | zLine = realloc(zLine, nLine); |
| 1383 | shell_check_oom(zLine); |
| 1384 | } |
| 1385 | if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ |
| @@ -1417,14 +1459,18 @@ | |
| 1459 | return -1; |
| 1460 | } |
| 1461 | |
| 1462 | /* |
| 1463 | ** Interpret zArg as an integer value, possibly with suffixes. |
| 1464 | ** |
| 1465 | ** If the value specified by zArg is outside the range of values that |
| 1466 | ** can be represented using a 64-bit twos-complement integer, then return |
| 1467 | ** the nearest representable value. |
| 1468 | */ |
| 1469 | static sqlite3_int64 integerValue(const char *zArg){ |
| 1470 | sqlite3_uint64 v = 0; |
| 1471 | static const struct { char *zSuffix; unsigned int iMult; } aMult[] = { |
| 1472 | { "KiB", 1024 }, |
| 1473 | { "MiB", 1024*1024 }, |
| 1474 | { "GiB", 1024*1024*1024 }, |
| 1475 | { "KB", 1000 }, |
| 1476 | { "MB", 1000000 }, |
| @@ -1443,46 +1489,54 @@ | |
| 1489 | } |
| 1490 | if( zArg[0]=='0' && zArg[1]=='x' ){ |
| 1491 | int x; |
| 1492 | zArg += 2; |
| 1493 | while( (x = hexDigitValue(zArg[0]))>=0 ){ |
| 1494 | if( v > 0x0fffffffffffffffULL ) goto integer_overflow; |
| 1495 | v = (v<<4) + x; |
| 1496 | zArg++; |
| 1497 | } |
| 1498 | }else{ |
| 1499 | while( IsDigit(zArg[0]) ){ |
| 1500 | if( v>=922337203685477580LL ){ |
| 1501 | if( v>922337203685477580LL || zArg[0]>='8' ) goto integer_overflow; |
| 1502 | } |
| 1503 | v = v*10 + (zArg[0] - '0'); |
| 1504 | zArg++; |
| 1505 | } |
| 1506 | } |
| 1507 | for(i=0; i<ArraySize(aMult); i++){ |
| 1508 | if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ |
| 1509 | if( 0x7fffffffffffffffULL/aMult[i].iMult < v ) goto integer_overflow; |
| 1510 | v *= aMult[i].iMult; |
| 1511 | break; |
| 1512 | } |
| 1513 | } |
| 1514 | if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow; |
| 1515 | return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v; |
| 1516 | integer_overflow: |
| 1517 | return isNeg ? (i64)0x8000000000000000LL : 0x7fffffffffffffffLL; |
| 1518 | } |
| 1519 | |
| 1520 | /* |
| 1521 | ** A variable length string to which one can append text. |
| 1522 | */ |
| 1523 | typedef struct ShellText ShellText; |
| 1524 | struct ShellText { |
| 1525 | char *zTxt; /* The text */ |
| 1526 | i64 n; /* Number of bytes of zTxt[] actually used */ |
| 1527 | i64 nAlloc; /* Number of bytes allocated for zTxt[] */ |
| 1528 | }; |
| 1529 | |
| 1530 | /* |
| 1531 | ** Initialize and destroy a ShellText object |
| 1532 | */ |
| 1533 | static void initText(ShellText *p){ |
| 1534 | memset(p, 0, sizeof(*p)); |
| 1535 | } |
| 1536 | static void freeText(ShellText *p){ |
| 1537 | sqlite3_free(p->zTxt); |
| 1538 | initText(p); |
| 1539 | } |
| 1540 | |
| 1541 | /* zIn is either a pointer to a NULL-terminated string in memory obtained |
| 1542 | ** from malloc(), or a NULL pointer. The string pointed to by zAppend is |
| @@ -1503,30 +1557,30 @@ | |
| 1557 | for(i=0; i<nAppend; i++){ |
| 1558 | if( zAppend[i]==quote ) len++; |
| 1559 | } |
| 1560 | } |
| 1561 | |
| 1562 | if( p->zTxt==0 || p->n+len>=p->nAlloc ){ |
| 1563 | p->nAlloc = p->nAlloc*2 + len + 20; |
| 1564 | p->zTxt = sqlite3_realloc64(p->zTxt, p->nAlloc); |
| 1565 | shell_check_oom(p->zTxt); |
| 1566 | } |
| 1567 | |
| 1568 | if( quote ){ |
| 1569 | char *zCsr = p->zTxt+p->n; |
| 1570 | *zCsr++ = quote; |
| 1571 | for(i=0; i<nAppend; i++){ |
| 1572 | *zCsr++ = zAppend[i]; |
| 1573 | if( zAppend[i]==quote ) *zCsr++ = quote; |
| 1574 | } |
| 1575 | *zCsr++ = quote; |
| 1576 | p->n = (i64)(zCsr - p->zTxt); |
| 1577 | *zCsr = '\0'; |
| 1578 | }else{ |
| 1579 | memcpy(p->zTxt+p->n, zAppend, nAppend); |
| 1580 | p->n += nAppend; |
| 1581 | p->zTxt[p->n] = '\0'; |
| 1582 | } |
| 1583 | } |
| 1584 | |
| 1585 | /* |
| 1586 | ** Attempt to determine if identifier zName needs to be quoted, either |
| @@ -1547,10 +1601,13 @@ | |
| 1601 | } |
| 1602 | |
| 1603 | /* |
| 1604 | ** Construct a fake object name and column list to describe the structure |
| 1605 | ** of the view, virtual table, or table valued function zSchema.zName. |
| 1606 | ** |
| 1607 | ** The returned string comes from sqlite3_mprintf() and should be freed |
| 1608 | ** by the caller using sqlite3_free(). |
| 1609 | */ |
| 1610 | static char *shellFakeSchema( |
| 1611 | sqlite3 *db, /* The database connection containing the vtab */ |
| 1612 | const char *zSchema, /* Schema of the database holding the vtab */ |
| 1613 | const char *zName /* The name of the virtual table */ |
| @@ -1587,13 +1644,13 @@ | |
| 1644 | } |
| 1645 | appendText(&s, ")", 0); |
| 1646 | sqlite3_finalize(pStmt); |
| 1647 | if( nRow==0 ){ |
| 1648 | freeText(&s); |
| 1649 | s.zTxt = 0; |
| 1650 | } |
| 1651 | return s.zTxt; |
| 1652 | } |
| 1653 | |
| 1654 | /* |
| 1655 | ** SQL function: strtod(X) |
| 1656 | ** |
| @@ -1692,11 +1749,11 @@ | |
| 1749 | if( z==0 ){ |
| 1750 | z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake); |
| 1751 | }else{ |
| 1752 | z = sqlite3_mprintf("%z\n/* %s */", z, zFake); |
| 1753 | } |
| 1754 | sqlite3_free(zFake); |
| 1755 | } |
| 1756 | if( z ){ |
| 1757 | sqlite3_result_text(pCtx, z, -1, sqlite3_free); |
| 1758 | return; |
| 1759 | } |
| @@ -3667,11 +3724,12 @@ | |
| 3724 | iExp -= p->nFrac; |
| 3725 | p->nFrac = 0; |
| 3726 | } |
| 3727 | } |
| 3728 | if( iExp>0 ){ |
| 3729 | p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit |
| 3730 | + (sqlite3_int64)iExp + 1 ); |
| 3731 | if( p->a==0 ) goto new_from_text_failed; |
| 3732 | memset(p->a+p->nDigit, 0, iExp); |
| 3733 | p->nDigit += iExp; |
| 3734 | } |
| 3735 | }else if( iExp<0 ){ |
| @@ -3686,18 +3744,23 @@ | |
| 3744 | iExp -= nExtra; |
| 3745 | p->nFrac = p->nDigit - 1; |
| 3746 | } |
| 3747 | } |
| 3748 | if( iExp>0 ){ |
| 3749 | p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit |
| 3750 | + (sqlite3_int64)iExp + 1 ); |
| 3751 | if( p->a==0 ) goto new_from_text_failed; |
| 3752 | memmove(p->a+iExp, p->a, p->nDigit); |
| 3753 | memset(p->a, 0, iExp); |
| 3754 | p->nDigit += iExp; |
| 3755 | p->nFrac += iExp; |
| 3756 | } |
| 3757 | } |
| 3758 | if( p->sign ){ |
| 3759 | for(i=0; i<p->nDigit && p->a[i]==0; i++){} |
| 3760 | if( i>=p->nDigit ) p->sign = 0; |
| 3761 | } |
| 3762 | return p; |
| 3763 | |
| 3764 | new_from_text_failed: |
| 3765 | if( p ){ |
| 3766 | if( p->a ) sqlite3_free(p->a); |
| @@ -3786,11 +3849,11 @@ | |
| 3849 | } |
| 3850 | if( p->isNull ){ |
| 3851 | sqlite3_result_null(pCtx); |
| 3852 | return; |
| 3853 | } |
| 3854 | z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+4 ); |
| 3855 | if( z==0 ){ |
| 3856 | sqlite3_result_error_nomem(pCtx); |
| 3857 | return; |
| 3858 | } |
| 3859 | i = 0; |
| @@ -3851,11 +3914,11 @@ | |
| 3914 | } |
| 3915 | for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){} |
| 3916 | for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){} |
| 3917 | nFrac = p->nFrac + (nDigit - p->nDigit); |
| 3918 | nDigit -= nZero; |
| 3919 | z = sqlite3_malloc64( (sqlite3_int64)nDigit+20 ); |
| 3920 | if( z==0 ){ |
| 3921 | sqlite3_result_error_nomem(pCtx); |
| 3922 | return; |
| 3923 | } |
| 3924 | if( nDigit==0 ){ |
| @@ -3896,17 +3959,25 @@ | |
| 3959 | ** pA!=0 |
| 3960 | ** pA->isNull==0 |
| 3961 | ** pB!=0 |
| 3962 | ** pB->isNull==0 |
| 3963 | */ |
| 3964 | static int decimal_cmp(Decimal *pA, Decimal *pB){ |
| 3965 | int nASig, nBSig, rc, n; |
| 3966 | while( pA->nFrac>0 && pA->a[pA->nDigit-1]==0 ){ |
| 3967 | pA->nDigit--; |
| 3968 | pA->nFrac--; |
| 3969 | } |
| 3970 | while( pB->nFrac>0 && pB->a[pB->nDigit-1]==0 ){ |
| 3971 | pB->nDigit--; |
| 3972 | pB->nFrac--; |
| 3973 | } |
| 3974 | if( pA->sign!=pB->sign ){ |
| 3975 | return pA->sign ? -1 : +1; |
| 3976 | } |
| 3977 | if( pA->sign ){ |
| 3978 | Decimal *pTemp = pA; |
| 3979 | pA = pB; |
| 3980 | pB = pTemp; |
| 3981 | } |
| 3982 | nASig = pA->nDigit - pA->nFrac; |
| 3983 | nBSig = pB->nDigit - pB->nFrac; |
| @@ -4064,11 +4135,12 @@ | |
| 4135 | if( pA==0 || pA->oom || pA->isNull |
| 4136 | || pB==0 || pB->oom || pB->isNull |
| 4137 | ){ |
| 4138 | goto mul_end; |
| 4139 | } |
| 4140 | acc = sqlite3_malloc64( (sqlite3_int64)pA->nDigit + |
| 4141 | (sqlite3_int64)pB->nDigit + 2 ); |
| 4142 | if( acc==0 ){ |
| 4143 | pA->oom = 1; |
| 4144 | goto mul_end; |
| 4145 | } |
| 4146 | memset(acc, 0, pA->nDigit + pB->nDigit + 2); |
| @@ -4151,11 +4223,11 @@ | |
| 4223 | r = -r; |
| 4224 | }else{ |
| 4225 | isNeg = 0; |
| 4226 | } |
| 4227 | memcpy(&a,&r,sizeof(a)); |
| 4228 | if( a==0 || a==(sqlite3_int64)0x8000000000000000LL){ |
| 4229 | e = 0; |
| 4230 | m = 0; |
| 4231 | }else{ |
| 4232 | e = a>>52; |
| 4233 | m = a & ((((sqlite3_int64)1)<<52)-1); |
| @@ -4426,516 +4498,10 @@ | |
| 4498 | } |
| 4499 | return rc; |
| 4500 | } |
| 4501 | |
| 4502 | /************************* End ../ext/misc/decimal.c ********************/ |
| 4503 | #undef sqlite3_base_init |
| 4504 | #define sqlite3_base_init sqlite3_base64_init |
| 4505 | /************************* Begin ../ext/misc/base64.c ******************/ |
| 4506 | /* |
| 4507 | ** 2022-11-18 |
| @@ -5144,20 +4710,22 @@ | |
| 4710 | return pOut; |
| 4711 | } |
| 4712 | |
| 4713 | /* This function does the work for the SQLite base64(x) UDF. */ |
| 4714 | static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){ |
| 4715 | sqlite3_int64 nb; |
| 4716 | sqlite3_int64 nv = sqlite3_value_bytes(av[0]); |
| 4717 | sqlite3_int64 nc; |
| 4718 | int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), |
| 4719 | SQLITE_LIMIT_LENGTH, -1); |
| 4720 | char *cBuf; |
| 4721 | u8 *bBuf; |
| 4722 | assert(na==1); |
| 4723 | switch( sqlite3_value_type(av[0]) ){ |
| 4724 | case SQLITE_BLOB: |
| 4725 | nb = nv; |
| 4726 | nc = 4*((nv+2)/3); /* quads needed */ |
| 4727 | nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */ |
| 4728 | if( nvMax < nc ){ |
| 4729 | sqlite3_result_error(context, "blob expanded to base64 too big", -1); |
| 4730 | return; |
| 4731 | } |
| @@ -5524,11 +5092,11 @@ | |
| 5092 | } |
| 5093 | # endif |
| 5094 | |
| 5095 | /* This function does the work for the SQLite base85(x) UDF. */ |
| 5096 | static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){ |
| 5097 | sqlite3_int64 nb, nc, nv = sqlite3_value_bytes(av[0]); |
| 5098 | int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), |
| 5099 | SQLITE_LIMIT_LENGTH, -1); |
| 5100 | char *cBuf; |
| 5101 | u8 *bBuf; |
| 5102 | assert(na==1); |
| @@ -5829,10 +5397,13 @@ | |
| 5397 | } |
| 5398 | memcpy(&a,&r,sizeof(a)); |
| 5399 | if( a==0 ){ |
| 5400 | e = 0; |
| 5401 | m = 0; |
| 5402 | }else if( a==(sqlite3_int64)0x8000000000000000LL ){ |
| 5403 | e = -1996; |
| 5404 | m = -1; |
| 5405 | }else{ |
| 5406 | e = a>>52; |
| 5407 | m = a & ((((sqlite3_int64)1)<<52)-1); |
| 5408 | if( e==0 ){ |
| 5409 | m <<= 1; |
| @@ -6052,23 +5623,24 @@ | |
| 5623 | ** Examples: |
| 5624 | ** |
| 5625 | ** SELECT * FROM generate_series(0,100,5); |
| 5626 | ** |
| 5627 | ** The query above returns integers from 0 through 100 counting by steps |
| 5628 | ** of 5. In other words, 0, 5, 10, 15, ..., 90, 95, 100. There are a total |
| 5629 | ** of 21 rows. |
| 5630 | ** |
| 5631 | ** SELECT * FROM generate_series(0,100); |
| 5632 | ** |
| 5633 | ** Integers from 0 through 100 with a step size of 1. 101 rows. |
| 5634 | ** |
| 5635 | ** SELECT * FROM generate_series(20) LIMIT 10; |
| 5636 | ** |
| 5637 | ** Integers 20 through 29. 10 rows. |
| 5638 | ** |
| 5639 | ** SELECT * FROM generate_series(0,-100,-5); |
| 5640 | ** |
| 5641 | ** Integers 0 -5 -10 ... -100. 21 rows. |
| 5642 | ** |
| 5643 | ** SELECT * FROM generate_series(0,-1); |
| 5644 | ** |
| 5645 | ** Empty sequence. |
| 5646 | ** |
| @@ -6140,143 +5712,92 @@ | |
| 5712 | #include <string.h> |
| 5713 | #include <limits.h> |
| 5714 | #include <math.h> |
| 5715 | |
| 5716 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 5717 | |
| 5718 | /* series_cursor is a subclass of sqlite3_vtab_cursor which will |
| 5719 | ** serve as the underlying representation of a cursor that scans |
| 5720 | ** over rows of the result. |
| 5721 | ** |
| 5722 | ** iOBase, iOTerm, and iOStep are the original values of the |
| 5723 | ** start=, stop=, and step= constraints on the query. These are |
| 5724 | ** the values reported by the start, stop, and step columns of the |
| 5725 | ** virtual table. |
| 5726 | ** |
| 5727 | ** iBase, iTerm, iStep, and bDescp are the actual values used to generate |
| 5728 | ** the sequence. These might be different from the iOxxxx values. |
| 5729 | ** For example in |
| 5730 | ** |
| 5731 | ** SELECT value FROM generate_series(1,11,2) |
| 5732 | ** WHERE value BETWEEN 4 AND 8; |
| 5733 | ** |
| 5734 | ** The iOBase is 1, but the iBase is 5. iOTerm is 11 but iTerm is 7. |
| 5735 | ** Another example: |
| 5736 | ** |
| 5737 | ** SELECT value FROM generate_series(1,15,3) ORDER BY value DESC; |
| 5738 | ** |
| 5739 | ** The cursor initialization for the above query is: |
| 5740 | ** |
| 5741 | ** iOBase = 1 iBase = 13 |
| 5742 | ** iOTerm = 15 iTerm = 1 |
| 5743 | ** iOStep = 3 iStep = 3 bDesc = 1 |
| 5744 | ** |
| 5745 | ** The actual step size is unsigned so that can have a value of |
| 5746 | ** +9223372036854775808 which is needed for querys like this: |
| 5747 | ** |
| 5748 | ** SELECT value |
| 5749 | ** FROM generate_series(9223372036854775807, |
| 5750 | ** -9223372036854775808, |
| 5751 | ** -9223372036854775808) |
| 5752 | ** ORDER BY value ASC; |
| 5753 | ** |
| 5754 | ** The setup for the previous query will be: |
| 5755 | ** |
| 5756 | ** iOBase = 9223372036854775807 iBase = -1 |
| 5757 | ** iOTerm = -9223372036854775808 iTerm = 9223372036854775807 |
| 5758 | ** iOStep = -9223372036854775808 iStep = 9223372036854775808 bDesc = 0 |
| 5759 | */ |
| 5760 | /* typedef unsigned char u8; */ |
| 5761 | typedef struct series_cursor series_cursor; |
| 5762 | struct series_cursor { |
| 5763 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 5764 | sqlite3_int64 iOBase; /* Original starting value ("start") */ |
| 5765 | sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ |
| 5766 | sqlite3_int64 iOStep; /* Original step value */ |
| 5767 | sqlite3_int64 iBase; /* Starting value to actually use */ |
| 5768 | sqlite3_int64 iTerm; /* Terminal value to actually use */ |
| 5769 | sqlite3_uint64 iStep; /* The step size */ |
| 5770 | sqlite3_int64 iValue; /* Current value */ |
| 5771 | u8 bDesc; /* iStep is really negative */ |
| 5772 | u8 bDone; /* True if stepped past last element */ |
| 5773 | }; |
| 5774 | |
| 5775 | /* |
| 5776 | ** Computed the difference between two 64-bit signed integers using a |
| 5777 | ** convoluted computation designed to work around the silly restriction |
| 5778 | ** against signed integer overflow in C. |
| 5779 | */ |
| 5780 | static sqlite3_uint64 span64(sqlite3_int64 a, sqlite3_int64 b){ |
| 5781 | assert( a>=b ); |
| 5782 | return (*(sqlite3_uint64*)&a) - (*(sqlite3_uint64*)&b); |
| 5783 | } |
| 5784 | |
| 5785 | /* |
| 5786 | ** Add or substract an unsigned 64-bit integer from a signed 64-bit integer |
| 5787 | ** and return the new signed 64-bit integer. |
| 5788 | */ |
| 5789 | static sqlite3_int64 add64(sqlite3_int64 a, sqlite3_uint64 b){ |
| 5790 | sqlite3_uint64 x = *(sqlite3_uint64*)&a; |
| 5791 | x += b; |
| 5792 | return *(sqlite3_int64*)&x; |
| 5793 | } |
| 5794 | static sqlite3_int64 sub64(sqlite3_int64 a, sqlite3_uint64 b){ |
| 5795 | sqlite3_uint64 x = *(sqlite3_uint64*)&a; |
| 5796 | x -= b; |
| 5797 | return *(sqlite3_int64*)&x; |
| 5798 | } |
| 5799 | |
| 5800 | /* |
| 5801 | ** The seriesConnect() method is invoked to create a new |
| 5802 | ** series_vtab that describes the generate_series virtual table. |
| 5803 | ** |
| @@ -6354,11 +5875,19 @@ | |
| 5875 | /* |
| 5876 | ** Advance a series_cursor to its next row of output. |
| 5877 | */ |
| 5878 | static int seriesNext(sqlite3_vtab_cursor *cur){ |
| 5879 | series_cursor *pCur = (series_cursor*)cur; |
| 5880 | if( pCur->iValue==pCur->iTerm ){ |
| 5881 | pCur->bDone = 1; |
| 5882 | }else if( pCur->bDesc ){ |
| 5883 | pCur->iValue = sub64(pCur->iValue, pCur->iStep); |
| 5884 | assert( pCur->iValue>=pCur->iTerm ); |
| 5885 | }else{ |
| 5886 | pCur->iValue = add64(pCur->iValue, pCur->iStep); |
| 5887 | assert( pCur->iValue<=pCur->iTerm ); |
| 5888 | } |
| 5889 | return SQLITE_OK; |
| 5890 | } |
| 5891 | |
| 5892 | /* |
| 5893 | ** Return values of columns for the row at which the series_cursor |
| @@ -6370,41 +5899,41 @@ | |
| 5899 | int i /* Which column to return */ |
| 5900 | ){ |
| 5901 | series_cursor *pCur = (series_cursor*)cur; |
| 5902 | sqlite3_int64 x = 0; |
| 5903 | switch( i ){ |
| 5904 | case SERIES_COLUMN_START: x = pCur->iOBase; break; |
| 5905 | case SERIES_COLUMN_STOP: x = pCur->iOTerm; break; |
| 5906 | case SERIES_COLUMN_STEP: x = pCur->iOStep; break; |
| 5907 | default: x = pCur->iValue; break; |
| 5908 | } |
| 5909 | sqlite3_result_int64(ctx, x); |
| 5910 | return SQLITE_OK; |
| 5911 | } |
| 5912 | |
| 5913 | #ifndef LARGEST_UINT64 |
| 5914 | #define LARGEST_INT64 ((sqlite3_int64)0x7fffffffffffffffLL) |
| 5915 | #define LARGEST_UINT64 ((sqlite3_uint64)0xffffffffffffffffULL) |
| 5916 | #define SMALLEST_INT64 ((sqlite3_int64)0x8000000000000000LL) |
| 5917 | #endif |
| 5918 | |
| 5919 | /* |
| 5920 | ** The rowid is the same as the value. |
| 5921 | */ |
| 5922 | static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 5923 | series_cursor *pCur = (series_cursor*)cur; |
| 5924 | *pRowid = pCur->iValue; |
| 5925 | return SQLITE_OK; |
| 5926 | } |
| 5927 | |
| 5928 | /* |
| 5929 | ** Return TRUE if the cursor has been moved off of the last |
| 5930 | ** row of output. |
| 5931 | */ |
| 5932 | static int seriesEof(sqlite3_vtab_cursor *cur){ |
| 5933 | series_cursor *pCur = (series_cursor*)cur; |
| 5934 | return pCur->bDone; |
| 5935 | } |
| 5936 | |
| 5937 | /* True to cause run-time checking of the start=, stop=, and/or step= |
| 5938 | ** parameters. The only reason to do this is for testing the |
| 5939 | ** constraint checking logic for virtual tables in the SQLite core. |
| @@ -6411,10 +5940,63 @@ | |
| 5940 | */ |
| 5941 | #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY |
| 5942 | # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 |
| 5943 | #endif |
| 5944 | |
| 5945 | /* |
| 5946 | ** Return the number of steps between pCur->iBase and pCur->iTerm if |
| 5947 | ** the step width is pCur->iStep. |
| 5948 | */ |
| 5949 | static sqlite3_uint64 seriesSteps(series_cursor *pCur){ |
| 5950 | if( pCur->bDesc ){ |
| 5951 | assert( pCur->iBase >= pCur->iTerm ); |
| 5952 | return span64(pCur->iBase, pCur->iTerm)/pCur->iStep; |
| 5953 | }else{ |
| 5954 | assert( pCur->iBase <= pCur->iTerm ); |
| 5955 | return span64(pCur->iTerm, pCur->iBase)/pCur->iStep; |
| 5956 | } |
| 5957 | } |
| 5958 | |
| 5959 | #if defined(SQLITE_ENABLE_MATH_FUNCTIONS) || defined(_WIN32) |
| 5960 | /* |
| 5961 | ** Case 1 (the most common case): |
| 5962 | ** The standard math library is available so use ceil() and floor() from there. |
| 5963 | */ |
| 5964 | static double seriesCeil(double r){ return ceil(r); } |
| 5965 | static double seriesFloor(double r){ return floor(r); } |
| 5966 | #elif defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) |
| 5967 | /* |
| 5968 | ** Case 2 (2nd most common): Use GCC/Clang builtins |
| 5969 | */ |
| 5970 | static double seriesCeil(double r){ return __builtin_ceil(r); } |
| 5971 | static double seriesFloor(double r){ return __builtin_floor(r); } |
| 5972 | #else |
| 5973 | /* |
| 5974 | ** Case 3 (rarely happens): Use home-grown ceil() and floor() routines. |
| 5975 | */ |
| 5976 | static double seriesCeil(double r){ |
| 5977 | sqlite3_int64 x; |
| 5978 | if( r!=r ) return r; |
| 5979 | if( r<=(-4503599627370496.0) ) return r; |
| 5980 | if( r>=(+4503599627370496.0) ) return r; |
| 5981 | x = (sqlite3_int64)r; |
| 5982 | if( r==(double)x ) return r; |
| 5983 | if( r>(double)x ) x++; |
| 5984 | return (double)x; |
| 5985 | } |
| 5986 | static double seriesFloor(double r){ |
| 5987 | sqlite3_int64 x; |
| 5988 | if( r!=r ) return r; |
| 5989 | if( r<=(-4503599627370496.0) ) return r; |
| 5990 | if( r>=(+4503599627370496.0) ) return r; |
| 5991 | x = (sqlite3_int64)r; |
| 5992 | if( r==(double)x ) return r; |
| 5993 | if( r<(double)x ) x--; |
| 5994 | return (double)x; |
| 5995 | } |
| 5996 | #endif |
| 5997 | |
| 5998 | /* |
| 5999 | ** This method is called to "rewind" the series_cursor object back |
| 6000 | ** to the first row of output. This method is always called at least |
| 6001 | ** once prior to any call to seriesColumn() or seriesRowid() or |
| 6002 | ** seriesEof(). |
| @@ -6444,185 +6026,243 @@ | |
| 6026 | sqlite3_vtab_cursor *pVtabCursor, |
| 6027 | int idxNum, const char *idxStrUnused, |
| 6028 | int argc, sqlite3_value **argv |
| 6029 | ){ |
| 6030 | series_cursor *pCur = (series_cursor *)pVtabCursor; |
| 6031 | int iArg = 0; /* Arguments used so far */ |
| 6032 | int i; /* Loop counter */ |
| 6033 | sqlite3_int64 iMin = SMALLEST_INT64; /* Smallest allowed output value */ |
| 6034 | sqlite3_int64 iMax = LARGEST_INT64; /* Largest allowed output value */ |
| 6035 | sqlite3_int64 iLimit = 0; /* if >0, the value of the LIMIT */ |
| 6036 | sqlite3_int64 iOffset = 0; /* if >0, the value of the OFFSET */ |
| 6037 | |
| 6038 | (void)idxStrUnused; |
| 6039 | |
| 6040 | /* If any constraints have a NULL value, then return no rows. |
| 6041 | ** See ticket https://sqlite.org/src/info/fac496b61722daf2 |
| 6042 | */ |
| 6043 | for(i=0; i<argc; i++){ |
| 6044 | if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ |
| 6045 | goto series_no_rows; |
| 6046 | } |
| 6047 | } |
| 6048 | |
| 6049 | /* Capture the three HIDDEN parameters to the virtual table and insert |
| 6050 | ** default values for any parameters that are omitted. |
| 6051 | */ |
| 6052 | if( idxNum & 0x01 ){ |
| 6053 | pCur->iOBase = sqlite3_value_int64(argv[iArg++]); |
| 6054 | }else{ |
| 6055 | pCur->iOBase = 0; |
| 6056 | } |
| 6057 | if( idxNum & 0x02 ){ |
| 6058 | pCur->iOTerm = sqlite3_value_int64(argv[iArg++]); |
| 6059 | }else{ |
| 6060 | pCur->iOTerm = 0xffffffff; |
| 6061 | } |
| 6062 | if( idxNum & 0x04 ){ |
| 6063 | pCur->iOStep = sqlite3_value_int64(argv[iArg++]); |
| 6064 | if( pCur->iOStep==0 ) pCur->iOStep = 1; |
| 6065 | }else{ |
| 6066 | pCur->iOStep = 1; |
| 6067 | } |
| 6068 | |
| 6069 | /* If there are constraints on the value column but there are |
| 6070 | ** no constraints on the start, stop, and step columns, then |
| 6071 | ** initialize the default range to be the entire range of 64-bit signed |
| 6072 | ** integers. This range will contracted by the value column constraints |
| 6073 | ** further below. |
| 6074 | */ |
| 6075 | if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ |
| 6076 | pCur->iOBase = SMALLEST_INT64; |
| 6077 | } |
| 6078 | if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ |
| 6079 | pCur->iOTerm = LARGEST_INT64; |
| 6080 | } |
| 6081 | pCur->iBase = pCur->iOBase; |
| 6082 | pCur->iTerm = pCur->iOTerm; |
| 6083 | if( pCur->iOStep>0 ){ |
| 6084 | pCur->iStep = pCur->iOStep; |
| 6085 | }else if( pCur->iOStep>SMALLEST_INT64 ){ |
| 6086 | pCur->iStep = -pCur->iOStep; |
| 6087 | }else{ |
| 6088 | pCur->iStep = LARGEST_INT64; |
| 6089 | pCur->iStep++; |
| 6090 | } |
| 6091 | pCur->bDesc = pCur->iOStep<0; |
| 6092 | if( pCur->bDesc==0 && pCur->iBase>pCur->iTerm ){ |
| 6093 | goto series_no_rows; |
| 6094 | } |
| 6095 | if( pCur->bDesc!=0 && pCur->iBase<pCur->iTerm ){ |
| 6096 | goto series_no_rows; |
| 6097 | } |
| 6098 | |
| 6099 | /* Extract the LIMIT and OFFSET values, but do not apply them yet. |
| 6100 | ** The range must first be constrained by the limits on value. |
| 6101 | */ |
| 6102 | if( idxNum & 0x20 ){ |
| 6103 | iLimit = sqlite3_value_int64(argv[iArg++]); |
| 6104 | if( idxNum & 0x40 ){ |
| 6105 | iOffset = sqlite3_value_int64(argv[iArg++]); |
| 6106 | } |
| 6107 | } |
| 6108 | |
| 6109 | /* Narrow the range of iMin and iMax (the minimum and maximum outputs) |
| 6110 | ** based on equality and inequality constraints on the "value" column. |
| 6111 | */ |
| 6112 | if( idxNum & 0x3380 ){ |
| 6113 | if( idxNum & 0x0080 ){ /* value=X */ |
| 6114 | if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ |
| 6115 | double r = sqlite3_value_double(argv[iArg++]); |
| 6116 | if( r==seriesCeil(r) |
| 6117 | && r>=(double)SMALLEST_INT64 |
| 6118 | && r<=(double)LARGEST_INT64 |
| 6119 | ){ |
| 6120 | iMin = iMax = (sqlite3_int64)r; |
| 6121 | }else{ |
| 6122 | goto series_no_rows; |
| 6123 | } |
| 6124 | }else{ |
| 6125 | iMin = iMax = sqlite3_value_int64(argv[iArg++]); |
| 6126 | } |
| 6127 | }else{ |
| 6128 | if( idxNum & 0x0300 ){ /* value>X or value>=X */ |
| 6129 | if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ |
| 6130 | double r = sqlite3_value_double(argv[iArg++]); |
| 6131 | if( r<(double)SMALLEST_INT64 ){ |
| 6132 | iMin = SMALLEST_INT64; |
| 6133 | }else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){ |
| 6134 | iMin = (sqlite3_int64)seriesCeil(r+1.0); |
| 6135 | }else{ |
| 6136 | iMin = (sqlite3_int64)seriesCeil(r); |
| 6137 | } |
| 6138 | }else{ |
| 6139 | iMin = sqlite3_value_int64(argv[iArg++]); |
| 6140 | if( (idxNum & 0x0200)!=0 ){ |
| 6141 | if( iMin==LARGEST_INT64 ){ |
| 6142 | goto series_no_rows; |
| 6143 | }else{ |
| 6144 | iMin++; |
| 6145 | } |
| 6146 | } |
| 6147 | } |
| 6148 | } |
| 6149 | if( idxNum & 0x3000 ){ /* value<X or value<=X */ |
| 6150 | if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ |
| 6151 | double r = sqlite3_value_double(argv[iArg++]); |
| 6152 | if( r>(double)LARGEST_INT64 ){ |
| 6153 | iMax = LARGEST_INT64; |
| 6154 | }else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){ |
| 6155 | iMax = (sqlite3_int64)(r-1.0); |
| 6156 | }else{ |
| 6157 | iMax = (sqlite3_int64)seriesFloor(r); |
| 6158 | } |
| 6159 | }else{ |
| 6160 | iMax = sqlite3_value_int64(argv[iArg++]); |
| 6161 | if( idxNum & 0x2000 ){ |
| 6162 | if( iMax==SMALLEST_INT64 ){ |
| 6163 | goto series_no_rows; |
| 6164 | }else{ |
| 6165 | iMax--; |
| 6166 | } |
| 6167 | } |
| 6168 | } |
| 6169 | } |
| 6170 | if( iMin>iMax ){ |
| 6171 | goto series_no_rows; |
| 6172 | } |
| 6173 | } |
| 6174 | |
| 6175 | /* Try to reduce the range of values to be generated based on |
| 6176 | ** constraints on the "value" column. |
| 6177 | */ |
| 6178 | if( pCur->bDesc==0 ){ |
| 6179 | if( pCur->iBase<iMin ){ |
| 6180 | sqlite3_uint64 span = span64(iMin,pCur->iBase); |
| 6181 | pCur->iBase = add64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); |
| 6182 | if( pCur->iBase<iMin ){ |
| 6183 | if( pCur->iBase > sub64(LARGEST_INT64, pCur->iStep) ){ |
| 6184 | goto series_no_rows; |
| 6185 | } |
| 6186 | pCur->iBase = add64(pCur->iBase, pCur->iStep); |
| 6187 | } |
| 6188 | } |
| 6189 | if( pCur->iTerm>iMax ){ |
| 6190 | pCur->iTerm = iMax; |
| 6191 | } |
| 6192 | }else{ |
| 6193 | if( pCur->iBase>iMax ){ |
| 6194 | sqlite3_uint64 span = span64(pCur->iBase,iMax); |
| 6195 | pCur->iBase = sub64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); |
| 6196 | if( pCur->iBase>iMax ){ |
| 6197 | if( pCur->iBase < add64(SMALLEST_INT64, pCur->iStep) ){ |
| 6198 | goto series_no_rows; |
| 6199 | } |
| 6200 | pCur->iBase = sub64(pCur->iBase, pCur->iStep); |
| 6201 | } |
| 6202 | } |
| 6203 | if( pCur->iTerm<iMin ){ |
| 6204 | pCur->iTerm = iMin; |
| 6205 | } |
| 6206 | } |
| 6207 | } |
| 6208 | |
| 6209 | /* Adjust iTerm so that it is exactly the last value of the series. |
| 6210 | */ |
| 6211 | if( pCur->bDesc==0 ){ |
| 6212 | if( pCur->iBase>pCur->iTerm ){ |
| 6213 | goto series_no_rows; |
| 6214 | } |
| 6215 | pCur->iTerm = sub64(pCur->iTerm, |
| 6216 | span64(pCur->iTerm,pCur->iBase) % pCur->iStep); |
| 6217 | }else{ |
| 6218 | if( pCur->iBase<pCur->iTerm ){ |
| 6219 | goto series_no_rows; |
| 6220 | } |
| 6221 | pCur->iTerm = add64(pCur->iTerm, |
| 6222 | span64(pCur->iBase,pCur->iTerm) % pCur->iStep); |
| 6223 | } |
| 6224 | |
| 6225 | /* Transform the series generator to output values in the requested |
| 6226 | ** order. |
| 6227 | */ |
| 6228 | if( ((idxNum & 0x0008)!=0 && pCur->bDesc==0) |
| 6229 | || ((idxNum & 0x0010)!=0 && pCur->bDesc!=0) |
| 6230 | ){ |
| 6231 | sqlite3_int64 tmp = pCur->iBase; |
| 6232 | pCur->iBase = pCur->iTerm; |
| 6233 | pCur->iTerm = tmp; |
| 6234 | pCur->bDesc = !pCur->bDesc; |
| 6235 | } |
| 6236 | |
| 6237 | /* Apply LIMIT and OFFSET constraints, if any */ |
| 6238 | assert( pCur->iStep!=0 ); |
| 6239 | if( idxNum & 0x20 ){ |
| 6240 | if( iOffset>0 ){ |
| 6241 | if( seriesSteps(pCur) < (sqlite3_uint64)iOffset ){ |
| 6242 | goto series_no_rows; |
| 6243 | }else if( pCur->bDesc ){ |
| 6244 | pCur->iBase = sub64(pCur->iBase, pCur->iStep*iOffset); |
| 6245 | }else{ |
| 6246 | pCur->iBase = add64(pCur->iBase, pCur->iStep*iOffset); |
| 6247 | } |
| 6248 | } |
| 6249 | if( iLimit>=0 && seriesSteps(pCur) > (sqlite3_uint64)iLimit ){ |
| 6250 | pCur->iTerm = add64(pCur->iBase, (iLimit - 1)*pCur->iStep); |
| 6251 | } |
| 6252 | } |
| 6253 | pCur->iValue = pCur->iBase; |
| 6254 | pCur->bDone = 0; |
| 6255 | return SQLITE_OK; |
| 6256 | |
| 6257 | series_no_rows: |
| 6258 | pCur->iBase = 0; |
| 6259 | pCur->iTerm = 0; |
| 6260 | pCur->iStep = 1; |
| 6261 | pCur->bDesc = 0; |
| 6262 | pCur->bDone = 1; |
| 6263 | return SQLITE_OK; |
| 6264 | } |
| 6265 | |
| 6266 | /* |
| 6267 | ** SQLite will invoke this method one or more times while planning a query |
| 6268 | ** that uses the generate_series virtual table. This routine needs to create |
| @@ -6948,10 +6588,12 @@ | |
| 6588 | ** expression and M is the size of the input string. The matcher never |
| 6589 | ** exhibits exponential behavior. Note that the X{p,q} operator expands |
| 6590 | ** to p copies of X following by q-p copies of X? and that the size of the |
| 6591 | ** regular expression in the O(N*M) performance bound is computed after |
| 6592 | ** this expansion. |
| 6593 | ** |
| 6594 | ** To help prevent DoS attacks, the maximum size of the NFA is restricted. |
| 6595 | */ |
| 6596 | #include <string.h> |
| 6597 | #include <stdlib.h> |
| 6598 | /* #include "sqlite3ext.h" */ |
| 6599 | SQLITE_EXTENSION_INIT1 |
| @@ -6988,36 +6630,10 @@ | |
| 6630 | #define RE_OP_NOTDIGIT 14 /* Not a digit */ |
| 6631 | #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ |
| 6632 | #define RE_OP_NOTSPACE 16 /* Not a digit */ |
| 6633 | #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ |
| 6634 | #define RE_OP_ATSTART 18 /* Currently at the start of the string */ |
| 6635 | |
| 6636 | /* Each opcode is a "state" in the NFA */ |
| 6637 | typedef unsigned short ReStateNumber; |
| 6638 | |
| 6639 | /* Because this is an NFA and not a DFA, multiple states can be active at |
| @@ -7051,10 +6667,11 @@ | |
| 6667 | unsigned (*xNextChar)(ReInput*); /* Next character function */ |
| 6668 | unsigned char zInit[12]; /* Initial text to match */ |
| 6669 | int nInit; /* Number of bytes in zInit */ |
| 6670 | unsigned nState; /* Number of entries in aOp[] and aArg[] */ |
| 6671 | unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */ |
| 6672 | unsigned mxAlloc; /* Complexity limit */ |
| 6673 | }; |
| 6674 | |
| 6675 | /* Add a state to the given state set if it is not already there */ |
| 6676 | static void re_add_state(ReStateSet *pSet, int newState){ |
| 6677 | unsigned i; |
| @@ -7265,18 +6882,19 @@ | |
| 6882 | return rc; |
| 6883 | } |
| 6884 | |
| 6885 | /* Resize the opcode and argument arrays for an RE under construction. |
| 6886 | */ |
| 6887 | static int re_resize(ReCompiled *p, unsigned int N){ |
| 6888 | char *aOp; |
| 6889 | int *aArg; |
| 6890 | if( N>p->mxAlloc ){ p->zErr = "REGEXP pattern too big"; return 1; } |
| 6891 | aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0])); |
| 6892 | if( aOp==0 ){ p->zErr = "out of memory"; return 1; } |
| 6893 | p->aOp = aOp; |
| 6894 | aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0])); |
| 6895 | if( aArg==0 ){ p->zErr = "out of memory"; return 1; } |
| 6896 | p->aArg = aArg; |
| 6897 | p->nAlloc = N; |
| 6898 | return 0; |
| 6899 | } |
| 6900 | |
| @@ -7303,11 +6921,11 @@ | |
| 6921 | } |
| 6922 | |
| 6923 | /* Make a copy of N opcodes starting at iStart onto the end of the RE |
| 6924 | ** under construction. |
| 6925 | */ |
| 6926 | static void re_copy(ReCompiled *p, int iStart, unsigned int N){ |
| 6927 | if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return; |
| 6928 | memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0])); |
| 6929 | memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0])); |
| 6930 | p->nState += N; |
| 6931 | } |
| @@ -7456,22 +7074,30 @@ | |
| 7074 | case '^': { |
| 7075 | re_append(p, RE_OP_ATSTART, 0); |
| 7076 | break; |
| 7077 | } |
| 7078 | case '{': { |
| 7079 | unsigned int m = 0, n = 0; |
| 7080 | unsigned int sz, j; |
| 7081 | if( iPrev<0 ) return "'{m,n}' without operand"; |
| 7082 | while( (c=rePeek(p))>='0' && c<='9' ){ |
| 7083 | m = m*10 + c - '0'; |
| 7084 | if( m*2>p->mxAlloc ) return "REGEXP pattern too big"; |
| 7085 | p->sIn.i++; |
| 7086 | } |
| 7087 | n = m; |
| 7088 | if( c==',' ){ |
| 7089 | p->sIn.i++; |
| 7090 | n = 0; |
| 7091 | while( (c=rePeek(p))>='0' && c<='9' ){ |
| 7092 | n = n*10 + c-'0'; |
| 7093 | if( n*2>p->mxAlloc ) return "REGEXP pattern too big"; |
| 7094 | p->sIn.i++; |
| 7095 | } |
| 7096 | } |
| 7097 | if( c!='}' ) return "unmatched '{'"; |
| 7098 | if( n<m ) return "n less than m in '{m,n}'"; |
| 7099 | p->sIn.i++; |
| 7100 | sz = p->nState - iPrev; |
| 7101 | if( m==0 ){ |
| 7102 | if( n==0 ) return "both m and n are zero in '{m,n}'"; |
| 7103 | re_insert(p, iPrev, RE_OP_FORK, sz+1); |
| @@ -7483,11 +7109,11 @@ | |
| 7109 | for(j=m; j<n; j++){ |
| 7110 | re_append(p, RE_OP_FORK, sz+1); |
| 7111 | re_copy(p, iPrev, sz); |
| 7112 | } |
| 7113 | if( n==0 && m>0 ){ |
| 7114 | re_append(p, RE_OP_FORK, -(int)sz); |
| 7115 | } |
| 7116 | break; |
| 7117 | } |
| 7118 | case '[': { |
| 7119 | unsigned int iFirst = p->nState; |
| @@ -7549,12 +7175,11 @@ | |
| 7175 | |
| 7176 | /* Free and reclaim all the memory used by a previously compiled |
| 7177 | ** regular expression. Applications should invoke this routine once |
| 7178 | ** for every call to re_compile() to avoid memory leaks. |
| 7179 | */ |
| 7180 | static void re_free(ReCompiled *pRe){ |
| 7181 | if( pRe ){ |
| 7182 | sqlite3_free(pRe->aOp); |
| 7183 | sqlite3_free(pRe->aArg); |
| 7184 | sqlite3_free(pRe); |
| 7185 | } |
| @@ -7564,11 +7189,16 @@ | |
| 7189 | ** Compile a textual regular expression in zIn[] into a compiled regular |
| 7190 | ** expression suitable for us by re_match() and return a pointer to the |
| 7191 | ** compiled regular expression in *ppRe. Return NULL on success or an |
| 7192 | ** error message if something goes wrong. |
| 7193 | */ |
| 7194 | static const char *re_compile( |
| 7195 | ReCompiled **ppRe, /* OUT: write compiled NFA here */ |
| 7196 | const char *zIn, /* Input regular expression */ |
| 7197 | int mxRe, /* Complexity limit */ |
| 7198 | int noCase /* True for caseless comparisons */ |
| 7199 | ){ |
| 7200 | ReCompiled *pRe; |
| 7201 | const char *zErr; |
| 7202 | int i, j; |
| 7203 | |
| 7204 | *ppRe = 0; |
| @@ -7576,13 +7206,15 @@ | |
| 7206 | if( pRe==0 ){ |
| 7207 | return "out of memory"; |
| 7208 | } |
| 7209 | memset(pRe, 0, sizeof(*pRe)); |
| 7210 | pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char; |
| 7211 | pRe->mxAlloc = mxRe; |
| 7212 | if( re_resize(pRe, 30) ){ |
| 7213 | zErr = pRe->zErr; |
| 7214 | re_free(pRe); |
| 7215 | return zErr; |
| 7216 | } |
| 7217 | if( zIn[0]=='^' ){ |
| 7218 | zIn++; |
| 7219 | }else{ |
| 7220 | re_append(pRe, RE_OP_ANYSTAR, 0); |
| @@ -7630,10 +7262,18 @@ | |
| 7262 | if( j>0 && pRe->zInit[j-1]==0 ) j--; |
| 7263 | pRe->nInit = j; |
| 7264 | } |
| 7265 | return pRe->zErr; |
| 7266 | } |
| 7267 | |
| 7268 | /* |
| 7269 | ** Compute a reasonable limit on the length of the REGEXP NFA. |
| 7270 | */ |
| 7271 | static int re_maxlen(sqlite3_context *context){ |
| 7272 | sqlite3 *db = sqlite3_context_db_handle(context); |
| 7273 | return 75 + sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH,-1)/2; |
| 7274 | } |
| 7275 | |
| 7276 | /* |
| 7277 | ** Implementation of the regexp() SQL function. This function implements |
| 7278 | ** the build-in REGEXP operator. The first argument to the function is the |
| 7279 | ** pattern and the second argument is the string. So, the SQL statements: |
| @@ -7656,11 +7296,12 @@ | |
| 7296 | (void)argc; /* Unused */ |
| 7297 | pRe = sqlite3_get_auxdata(context, 0); |
| 7298 | if( pRe==0 ){ |
| 7299 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 7300 | if( zPattern==0 ) return; |
| 7301 | zErr = re_compile(&pRe, zPattern, re_maxlen(context), |
| 7302 | sqlite3_user_data(context)!=0); |
| 7303 | if( zErr ){ |
| 7304 | re_free(pRe); |
| 7305 | sqlite3_result_error(context, zErr, -1); |
| 7306 | return; |
| 7307 | } |
| @@ -7698,14 +7339,36 @@ | |
| 7339 | sqlite3_str *pStr; |
| 7340 | int i; |
| 7341 | int n; |
| 7342 | char *z; |
| 7343 | (void)argc; |
| 7344 | static const char *ReOpName[] = { |
| 7345 | "EOF", |
| 7346 | "MATCH", |
| 7347 | "ANY", |
| 7348 | "ANYSTAR", |
| 7349 | "FORK", |
| 7350 | "GOTO", |
| 7351 | "ACCEPT", |
| 7352 | "CC_INC", |
| 7353 | "CC_EXC", |
| 7354 | "CC_VALUE", |
| 7355 | "CC_RANGE", |
| 7356 | "WORD", |
| 7357 | "NOTWORD", |
| 7358 | "DIGIT", |
| 7359 | "NOTDIGIT", |
| 7360 | "SPACE", |
| 7361 | "NOTSPACE", |
| 7362 | "BOUNDARY", |
| 7363 | "ATSTART", |
| 7364 | }; |
| 7365 | |
| 7366 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
| 7367 | if( zPattern==0 ) return; |
| 7368 | zErr = re_compile(&pRe, zPattern, re_maxlen(context), |
| 7369 | sqlite3_user_data(context)!=0); |
| 7370 | if( zErr ){ |
| 7371 | re_free(pRe); |
| 7372 | sqlite3_result_error(context, zErr, -1); |
| 7373 | return; |
| 7374 | } |
| @@ -9284,18 +8947,20 @@ | |
| 8947 | if( idxNum & 1 ){ |
| 8948 | pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); |
| 8949 | if( pCur->nPrefix>0 ){ |
| 8950 | pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 8951 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 8952 | pCur->nPrefix = (int)strlen(pCur->zPrefix); |
| 8953 | } |
| 8954 | iArg = 1; |
| 8955 | } |
| 8956 | if( idxNum & 2 ){ |
| 8957 | pCur->nLine = sqlite3_value_bytes(argv[iArg]); |
| 8958 | if( pCur->nLine>0 ){ |
| 8959 | pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 8960 | if( pCur->zLine==0 ) return SQLITE_NOMEM; |
| 8961 | pCur->nLine = (int)strlen(pCur->zLine); |
| 8962 | } |
| 8963 | } |
| 8964 | if( pCur->zLine!=0 && pCur->zPrefix==0 ){ |
| 8965 | int i = pCur->nLine; |
| 8966 | while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ |
| @@ -9303,10 +8968,11 @@ | |
| 8968 | } |
| 8969 | pCur->nPrefix = pCur->nLine - i; |
| 8970 | if( pCur->nPrefix>0 ){ |
| 8971 | pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); |
| 8972 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 8973 | pCur->nPrefix = (int)strlen(pCur->zPrefix); |
| 8974 | } |
| 8975 | } |
| 8976 | pCur->iRowid = 0; |
| 8977 | pCur->ePhase = COMPLETION_FIRST_PHASE; |
| 8978 | return completionNext(pVtabCursor); |
| @@ -10216,11 +9882,17 @@ | |
| 9882 | "method," /* 6: Compression method (integer) */ |
| 9883 | "z HIDDEN" /* 7: Name of zip file */ |
| 9884 | ") WITHOUT ROWID;"; |
| 9885 | |
| 9886 | #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ |
| 9887 | #define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */ |
| 9888 | |
| 9889 | /* |
| 9890 | ** The buffer should be large enough to contain 3 65536 byte strings - the |
| 9891 | ** filename, the extra field and the file comment. |
| 9892 | */ |
| 9893 | #define ZIPFILE_BUFFER_SIZE (200*1024) |
| 9894 | |
| 9895 | |
| 9896 | /* |
| 9897 | ** Magic numbers used to read and write zip files. |
| 9898 | ** |
| @@ -10773,10 +10445,11 @@ | |
| 10445 | pLFH->crc32 = zipfileRead32(aRead); |
| 10446 | pLFH->szCompressed = zipfileRead32(aRead); |
| 10447 | pLFH->szUncompressed = zipfileRead32(aRead); |
| 10448 | pLFH->nFile = zipfileRead16(aRead); |
| 10449 | pLFH->nExtra = zipfileRead16(aRead); |
| 10450 | if( pLFH->nFile>ZIPFILE_MX_NAME ) rc = SQLITE_ERROR; |
| 10451 | } |
| 10452 | return rc; |
| 10453 | } |
| 10454 | |
| 10455 | |
| @@ -10898,10 +10571,19 @@ | |
| 10571 | || mUnixTime==zipfileMtime(pCds) |
| 10572 | || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) |
| 10573 | /* || (mUnixTime % 2) */ |
| 10574 | ); |
| 10575 | } |
| 10576 | |
| 10577 | /* |
| 10578 | ** Set (*pzErr) to point to a buffer from sqlite3_malloc() containing a |
| 10579 | ** generic corruption message and return SQLITE_CORRUPT; |
| 10580 | */ |
| 10581 | static int zipfileCorrupt(char **pzErr){ |
| 10582 | *pzErr = sqlite3_mprintf("zip archive is corrupt"); |
| 10583 | return SQLITE_CORRUPT; |
| 10584 | } |
| 10585 | |
| 10586 | /* |
| 10587 | ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in |
| 10588 | ** size) containing an entire zip archive image. Or, if aBlob is NULL, |
| 10589 | ** then pFile is a file-handle open on a zip file. In either case, this |
| @@ -10921,16 +10603,19 @@ | |
| 10603 | ZipfileEntry **ppEntry /* OUT: Pointer to new object */ |
| 10604 | ){ |
| 10605 | u8 *aRead; |
| 10606 | char **pzErr = &pTab->base.zErrMsg; |
| 10607 | int rc = SQLITE_OK; |
| 10608 | |
| 10609 | if( aBlob==0 ){ |
| 10610 | aRead = pTab->aBuffer; |
| 10611 | rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); |
| 10612 | }else{ |
| 10613 | if( (iOff+ZIPFILE_CDS_FIXED_SZ)>nBlob ){ |
| 10614 | /* Not enough data for the CDS structure. Corruption. */ |
| 10615 | return zipfileCorrupt(pzErr); |
| 10616 | } |
| 10617 | aRead = (u8*)&aBlob[iOff]; |
| 10618 | } |
| 10619 | |
| 10620 | if( rc==SQLITE_OK ){ |
| 10621 | sqlite3_int64 nAlloc; |
| @@ -10957,10 +10642,13 @@ | |
| 10642 | rc = zipfileReadData( |
| 10643 | pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr |
| 10644 | ); |
| 10645 | }else{ |
| 10646 | aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; |
| 10647 | if( (iOff + ZIPFILE_LFH_FIXED_SZ + nFile + nExtra)>nBlob ){ |
| 10648 | rc = zipfileCorrupt(pzErr); |
| 10649 | } |
| 10650 | } |
| 10651 | } |
| 10652 | |
| 10653 | if( rc==SQLITE_OK ){ |
| 10654 | u32 *pt = &pNew->mUnixTime; |
| @@ -10979,19 +10667,26 @@ | |
| 10667 | ZipfileLFH lfh; |
| 10668 | if( pFile ){ |
| 10669 | rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); |
| 10670 | }else{ |
| 10671 | aRead = (u8*)&aBlob[pNew->cds.iOffset]; |
| 10672 | if( (pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ)>nBlob ){ |
| 10673 | rc = zipfileCorrupt(pzErr); |
| 10674 | } |
| 10675 | } |
| 10676 | |
| 10677 | if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh); |
| 10678 | if( rc==SQLITE_OK ){ |
| 10679 | pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; |
| 10680 | pNew->iDataOff += lfh.nFile + lfh.nExtra; |
| 10681 | if( aBlob && pNew->cds.szCompressed ){ |
| 10682 | if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){ |
| 10683 | rc = zipfileCorrupt(pzErr); |
| 10684 | }else{ |
| 10685 | pNew->aData = &pNew->aExtra[nExtra]; |
| 10686 | memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); |
| 10687 | } |
| 10688 | } |
| 10689 | }else{ |
| 10690 | *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", |
| 10691 | (int)pNew->cds.iOffset |
| 10692 | ); |
| @@ -11774,10 +11469,15 @@ | |
| 11469 | |
| 11470 | if( rc==SQLITE_OK ){ |
| 11471 | zPath = (const char*)sqlite3_value_text(apVal[2]); |
| 11472 | if( zPath==0 ) zPath = ""; |
| 11473 | nPath = (int)strlen(zPath); |
| 11474 | if( nPath>ZIPFILE_MX_NAME ){ |
| 11475 | zipfileTableErr(pTab, "filename too long; max: %d bytes", |
| 11476 | ZIPFILE_MX_NAME); |
| 11477 | rc = SQLITE_CONSTRAINT; |
| 11478 | } |
| 11479 | mTime = zipfileGetTime(apVal[4]); |
| 11480 | } |
| 11481 | |
| 11482 | if( rc==SQLITE_OK && bIsDir ){ |
| 11483 | /* For a directory, check that the last character in the path is a |
| @@ -12135,10 +11835,17 @@ | |
| 11835 | if( zName==0 ){ |
| 11836 | zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL"); |
| 11837 | rc = SQLITE_ERROR; |
| 11838 | goto zipfile_step_out; |
| 11839 | } |
| 11840 | if( nName>ZIPFILE_MX_NAME ){ |
| 11841 | zErr = sqlite3_mprintf( |
| 11842 | "filename argument to zipfile() too big; max: %d bytes", |
| 11843 | ZIPFILE_MX_NAME); |
| 11844 | rc = SQLITE_ERROR; |
| 11845 | goto zipfile_step_out; |
| 11846 | } |
| 11847 | |
| 11848 | /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use |
| 11849 | ** deflate compression) or NULL (choose automatically). */ |
| 11850 | if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ |
| 11851 | iMethod = (int)sqlite3_value_int64(pMethod); |
| @@ -12477,10 +12184,11 @@ | |
| 12184 | return rc; |
| 12185 | } |
| 12186 | |
| 12187 | /************************* End ../ext/misc/sqlar.c ********************/ |
| 12188 | #endif |
| 12189 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 12190 | /************************* Begin ../ext/expert/sqlite3expert.h ******************/ |
| 12191 | /* |
| 12192 | ** 2017 April 07 |
| 12193 | ** |
| 12194 | ** The author disclaims copyright to this source code. In place of |
| @@ -14885,10 +14593,11 @@ | |
| 14593 | } |
| 14594 | |
| 14595 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
| 14596 | |
| 14597 | /************************* End ../ext/expert/sqlite3expert.c ********************/ |
| 14598 | #endif |
| 14599 | /************************* Begin ../ext/intck/sqlite3intck.h ******************/ |
| 14600 | /* |
| 14601 | ** 2024-02-08 |
| 14602 | ** |
| 14603 | ** The author disclaims copyright to this source code. In place of |
| @@ -21525,15 +21234,17 @@ | |
| 21234 | char **azFilter; /* Array of xFilter rejection GLOB patterns */ |
| 21235 | sqlite3_session *p; /* The open session */ |
| 21236 | }; |
| 21237 | #endif |
| 21238 | |
| 21239 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 21240 | typedef struct ExpertInfo ExpertInfo; |
| 21241 | struct ExpertInfo { |
| 21242 | sqlite3expert *pExpert; |
| 21243 | int bVerbose; |
| 21244 | }; |
| 21245 | #endif |
| 21246 | |
| 21247 | /* A single line in the EQP output */ |
| 21248 | typedef struct EQPGraphRow EQPGraphRow; |
| 21249 | struct EQPGraphRow { |
| 21250 | int iEqpId; /* ID for this row */ |
| @@ -21633,11 +21344,13 @@ | |
| 21344 | int *aiIndent; /* Array of indents used in MODE_Explain */ |
| 21345 | int nIndent; /* Size of array aiIndent[] */ |
| 21346 | int iIndent; /* Index of current op in aiIndent[] */ |
| 21347 | char *zNonce; /* Nonce for temporary safe-mode escapes */ |
| 21348 | EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ |
| 21349 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 21350 | ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ |
| 21351 | #endif |
| 21352 | #ifdef SQLITE_SHELL_FIDDLE |
| 21353 | struct { |
| 21354 | const char * zInput; /* Input string from wasm/JS proxy */ |
| 21355 | const char * zPos; /* Cursor pos into zInput */ |
| 21356 | const char * zDefaultDbName; /* Default name for db file */ |
| @@ -21661,13 +21374,12 @@ | |
| 21374 | */ |
| 21375 | #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ |
| 21376 | #define SHELL_OPEN_NORMAL 1 /* Normal database file */ |
| 21377 | #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ |
| 21378 | #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ |
| 21379 | #define SHELL_OPEN_DESERIALIZE 4 /* Open using sqlite3_deserialize() */ |
| 21380 | #define SHELL_OPEN_HEXDB 5 /* Use "dbtotxt" output as data source */ |
| 21381 | |
| 21382 | /* Allowed values for ShellState.eTraceType |
| 21383 | */ |
| 21384 | #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ |
| 21385 | #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ |
| @@ -22006,11 +21718,11 @@ | |
| 21718 | */ |
| 21719 | static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ |
| 21720 | int i; |
| 21721 | unsigned char *aBlob = (unsigned char*)pBlob; |
| 21722 | |
| 21723 | char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1); |
| 21724 | shell_check_oom(zStr); |
| 21725 | |
| 21726 | for(i=0; i<nBlob; i++){ |
| 21727 | static const char aHex[] = { |
| 21728 | '0', '1', '2', '3', '4', '5', '6', '7', |
| @@ -22027,11 +21739,11 @@ | |
| 21739 | |
| 21740 | /* |
| 21741 | ** Output the given string as a quoted string using SQL quoting conventions: |
| 21742 | ** |
| 21743 | ** (1) Single quotes (') within the string are doubled |
| 21744 | ** (2) The while string is enclosed in '...' |
| 21745 | ** (3) Control characters other than \n, \t, and \r\n are escaped |
| 21746 | ** using \u00XX notation and if such substitutions occur, |
| 21747 | ** the whole string is enclosed in unistr('...') instead of '...'. |
| 21748 | ** |
| 21749 | ** Step (3) is omitted if the control-character escape mode is OFF. |
| @@ -22273,11 +21985,11 @@ | |
| 21985 | ** |
| 21986 | ** Escaping is needed if the string contains any control characters |
| 21987 | ** other than \t, \n, and \r\n |
| 21988 | ** |
| 21989 | ** If no escaping is needed (the common case) then set *ppFree to NULL |
| 21990 | ** and return the original string. If escaping is needed, write the |
| 21991 | ** escaped string into memory obtained from sqlite3_malloc64() or the |
| 21992 | ** equivalent, and return the new string and set *ppFree to the new string |
| 21993 | ** as well. |
| 21994 | ** |
| 21995 | ** The caller is responsible for freeing *ppFree if it is non-NULL in order |
| @@ -23278,32 +22990,21 @@ | |
| 22990 | ** Set the destination table field of the ShellState structure to |
| 22991 | ** the name of the table given. Escape any quote characters in the |
| 22992 | ** table name. |
| 22993 | */ |
| 22994 | static void set_table_name(ShellState *p, const char *zName){ |
| 22995 | if( p->zDestTable ){ |
| 22996 | sqlite3_free(p->zDestTable); |
| 22997 | p->zDestTable = 0; |
| 22998 | } |
| 22999 | if( zName==0 ) return; |
| 23000 | if( quoteChar(zName) ){ |
| 23001 | p->zDestTable = sqlite3_mprintf("\"%w\"", zName); |
| 23002 | }else{ |
| 23003 | p->zDestTable = sqlite3_mprintf("%s", zName); |
| 23004 | } |
| 23005 | shell_check_oom(p->zDestTable); |
| 23006 | } |
| 23007 | |
| 23008 | /* |
| 23009 | ** Maybe construct two lines of text that point out the position of a |
| 23010 | ** syntax error. Return a pointer to the text, in memory obtained from |
| @@ -23496,12 +23197,12 @@ | |
| 23197 | static int display_stats( |
| 23198 | sqlite3 *db, /* Database to query */ |
| 23199 | ShellState *pArg, /* Pointer to ShellState */ |
| 23200 | int bReset /* True to reset the stats */ |
| 23201 | ){ |
| 23202 | int iCur, iHiwtr; |
| 23203 | sqlite3_int64 iCur64, iHiwtr64; |
| 23204 | FILE *out; |
| 23205 | if( pArg==0 || pArg->out==0 ) return 0; |
| 23206 | out = pArg->out; |
| 23207 | |
| 23208 | if( pArg->pStmt && pArg->statsOn==2 ){ |
| @@ -23586,18 +23287,25 @@ | |
| 23287 | "Page cache hits: %d\n", iCur); |
| 23288 | iHiwtr = iCur = -1; |
| 23289 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); |
| 23290 | sqlite3_fprintf(out, |
| 23291 | "Page cache misses: %d\n", iCur); |
| 23292 | iHiwtr64 = iCur64 = -1; |
| 23293 | sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64, |
| 23294 | 0); |
| 23295 | iHiwtr = iCur = -1; |
| 23296 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); |
| 23297 | sqlite3_fprintf(out, |
| 23298 | "Page cache writes: %d\n", iCur); |
| 23299 | iHiwtr = iCur = -1; |
| 23300 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); |
| 23301 | sqlite3_fprintf(out, |
| 23302 | "Page cache spills: %d\n", iCur); |
| 23303 | sqlite3_fprintf(out, |
| 23304 | "Temporary data spilled to disk: %lld\n", iCur64); |
| 23305 | sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64, |
| 23306 | 1); |
| 23307 | iHiwtr = iCur = -1; |
| 23308 | sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); |
| 23309 | sqlite3_fprintf(out, |
| 23310 | "Schema Heap Usage: %d bytes\n", iCur); |
| 23311 | iHiwtr = iCur = -1; |
| @@ -23999,10 +23707,40 @@ | |
| 23707 | char *zBuf = sqlite3_malloc64( szVar-5 ); |
| 23708 | if( zBuf ){ |
| 23709 | memcpy(zBuf, &zVar[6], szVar-5); |
| 23710 | sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8); |
| 23711 | } |
| 23712 | #ifdef SQLITE_ENABLE_CARRAY |
| 23713 | }else if( strncmp(zVar, "$carray_", 8)==0 ){ |
| 23714 | static char *azColorNames[] = { |
| 23715 | "azure", "black", "blue", "brown", "cyan", "fuchsia", "gold", |
| 23716 | "gray", "green", "indigo", "khaki", "lime", "magenta", "maroon", |
| 23717 | "navy", "olive", "orange", "pink", "purple", "red", "silver", |
| 23718 | "tan", "teal", "violet", "white", "yellow" |
| 23719 | }; |
| 23720 | static int aPrimes[] = { |
| 23721 | 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, |
| 23722 | 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 |
| 23723 | }; |
| 23724 | /* Special bindings: carray($carray_clr), carray($carray_primes) |
| 23725 | ** with --unsafe-testing: carray($carray_clr_p,26,'char*'), |
| 23726 | ** carray($carray_primes_p,26,'int32') |
| 23727 | */ |
| 23728 | if( strcmp(zVar+8,"clr")==0 ){ |
| 23729 | sqlite3_carray_bind(pStmt,i,azColorNames,26,SQLITE_CARRAY_TEXT,0); |
| 23730 | }else if( strcmp(zVar+8,"primes")==0 ){ |
| 23731 | sqlite3_carray_bind(pStmt,i,aPrimes,26,SQLITE_CARRAY_INT32,0); |
| 23732 | }else if( strcmp(zVar+8,"clr_p")==0 |
| 23733 | && ShellHasFlag(pArg,SHFLG_TestingMode) ){ |
| 23734 | sqlite3_bind_pointer(pStmt,i,azColorNames,"carray",0); |
| 23735 | }else if( strcmp(zVar+8,"primes_p")==0 |
| 23736 | && ShellHasFlag(pArg,SHFLG_TestingMode) ){ |
| 23737 | sqlite3_bind_pointer(pStmt,i,aPrimes,"carray",0); |
| 23738 | }else{ |
| 23739 | sqlite3_bind_null(pStmt, i); |
| 23740 | } |
| 23741 | #endif |
| 23742 | }else{ |
| 23743 | sqlite3_bind_null(pStmt, i); |
| 23744 | } |
| 23745 | sqlite3_reset(pQ); |
| 23746 | } |
| @@ -24581,11 +24319,11 @@ | |
| 24319 | } |
| 24320 | } |
| 24321 | } |
| 24322 | } |
| 24323 | |
| 24324 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 24325 | /* |
| 24326 | ** This function is called to process SQL if the previous shell command |
| 24327 | ** was ".expert". It passes the SQL in the second argument directly to |
| 24328 | ** the sqlite3expert object. |
| 24329 | ** |
| @@ -24713,11 +24451,11 @@ | |
| 24451 | } |
| 24452 | sqlite3_free(zErr); |
| 24453 | |
| 24454 | return rc; |
| 24455 | } |
| 24456 | #endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */ |
| 24457 | |
| 24458 | /* |
| 24459 | ** Execute a statement or set of statements. Print |
| 24460 | ** any result rows/columns depending on the current mode |
| 24461 | ** set via the supplied callback. |
| @@ -24739,11 +24477,11 @@ | |
| 24477 | |
| 24478 | if( pzErrMsg ){ |
| 24479 | *pzErrMsg = NULL; |
| 24480 | } |
| 24481 | |
| 24482 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 24483 | if( pArg->expert.pExpert ){ |
| 24484 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
| 24485 | return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); |
| 24486 | } |
| 24487 | #endif |
| @@ -24901,11 +24639,11 @@ | |
| 24639 | static char **tableColumnList(ShellState *p, const char *zTab){ |
| 24640 | char **azCol = 0; |
| 24641 | sqlite3_stmt *pStmt; |
| 24642 | char *zSql; |
| 24643 | int nCol = 0; |
| 24644 | i64 nAlloc = 0; |
| 24645 | int nPK = 0; /* Number of PRIMARY KEY columns seen */ |
| 24646 | int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ |
| 24647 | int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); |
| 24648 | int rc; |
| 24649 | |
| @@ -24915,11 +24653,11 @@ | |
| 24653 | sqlite3_free(zSql); |
| 24654 | if( rc ) return 0; |
| 24655 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 24656 | if( nCol>=nAlloc-2 ){ |
| 24657 | nAlloc = nAlloc*2 + nCol + 10; |
| 24658 | azCol = sqlite3_realloc64(azCol, nAlloc*sizeof(azCol[0])); |
| 24659 | shell_check_oom(azCol); |
| 24660 | } |
| 24661 | azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); |
| 24662 | shell_check_oom(azCol[nCol]); |
| 24663 | if( sqlite3_column_int(pStmt, 5) ){ |
| @@ -25106,17 +24844,17 @@ | |
| 24844 | appendText(&sSelect, " FROM ", 0); |
| 24845 | appendText(&sSelect, zTable, quoteChar(zTable)); |
| 24846 | |
| 24847 | savedDestTable = p->zDestTable; |
| 24848 | savedMode = p->mode; |
| 24849 | p->zDestTable = sTable.zTxt; |
| 24850 | p->mode = p->cMode = MODE_Insert; |
| 24851 | rc = shell_exec(p, sSelect.zTxt, 0); |
| 24852 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
| 24853 | sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); |
| 24854 | toggleSelectOrder(p->db); |
| 24855 | shell_exec(p, sSelect.zTxt, 0); |
| 24856 | toggleSelectOrder(p->db); |
| 24857 | } |
| 24858 | p->zDestTable = savedDestTable; |
| 24859 | p->mode = savedMode; |
| 24860 | freeText(&sTable); |
| @@ -25245,11 +24983,13 @@ | |
| 24983 | " --bom Put a UTF8 byte-order mark on intermediate file", |
| 24984 | #endif |
| 24985 | #ifndef SQLITE_SHELL_FIDDLE |
| 24986 | ".exit ?CODE? Exit this program with return-code CODE", |
| 24987 | #endif |
| 24988 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 24989 | ".expert EXPERIMENTAL. Suggest indexes for queries", |
| 24990 | #endif |
| 24991 | ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto", |
| 24992 | ".filectrl CMD ... Run various sqlite3_file_control() operations", |
| 24993 | " --schema SCHEMA Use SCHEMA instead of \"main\"", |
| 24994 | " --help Show CMD details", |
| 24995 | ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", |
| @@ -25270,11 +25010,11 @@ | |
| 25010 | " from the \".mode\" output mode", |
| 25011 | " * If FILE begins with \"|\" then it is a command that generates the", |
| 25012 | " input text.", |
| 25013 | #endif |
| 25014 | #ifndef SQLITE_OMIT_TEST_CONTROL |
| 25015 | ".imposter INDEX TABLE Create imposter table TABLE on index INDEX", |
| 25016 | #endif |
| 25017 | ".indexes ?TABLE? Show names of indexes", |
| 25018 | " If TABLE is specified, only show indexes for", |
| 25019 | " tables matching TABLE using the LIKE operator.", |
| 25020 | ".intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db", |
| @@ -25337,11 +25077,17 @@ | |
| 25077 | " Options:", |
| 25078 | " --append Use appendvfs to append database to the end of FILE", |
| 25079 | #endif |
| 25080 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 25081 | " --deserialize Load into memory using sqlite3_deserialize()", |
| 25082 | #endif |
| 25083 | /*" --exclusive Set the SQLITE_OPEN_EXCLUSIVE flag", UNDOCUMENTED */ |
| 25084 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 25085 | " --hexdb Load the output of \"dbtotxt\" as an in-memory db", |
| 25086 | #endif |
| 25087 | " --ifexist Only open if FILE already exists", |
| 25088 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 25089 | " --maxsize N Maximum size for --hexdb or --deserialized database", |
| 25090 | #endif |
| 25091 | " --new Initialize FILE to an empty database", |
| 25092 | " --nofollow Do not follow symbolic links", |
| 25093 | " --readonly Open FILE readonly", |
| @@ -25726,14 +25472,14 @@ | |
| 25472 | ** If p->aAuxDb[].zDbFilename is 0, then read from standard input. |
| 25473 | */ |
| 25474 | static unsigned char *readHexDb(ShellState *p, int *pnData){ |
| 25475 | unsigned char *a = 0; |
| 25476 | int nLine; |
| 25477 | int n = 0; /* Size of db per first line of hex dump */ |
| 25478 | i64 sz = 0; /* n rounded up to nearest page boundary */ |
| 25479 | int pgsz = 0; |
| 25480 | i64 iOffset = 0; |
| 25481 | int rc; |
| 25482 | FILE *in; |
| 25483 | const char *zDbFilename = p->pAuxDb->zDbFilename; |
| 25484 | unsigned int x[16]; |
| 25485 | char zLine[1000]; |
| @@ -25753,20 +25499,21 @@ | |
| 25499 | nLine++; |
| 25500 | if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; |
| 25501 | rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); |
| 25502 | if( rc!=2 ) goto readHexDb_error; |
| 25503 | if( n<0 ) goto readHexDb_error; |
| 25504 | if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
| 25505 | sqlite3_fputs("invalid pagesize\n", stderr); |
| 25506 | goto readHexDb_error; |
| 25507 | } |
| 25508 | sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */ |
| 25509 | a = sqlite3_malloc64( sz ? sz : 1 ); |
| 25510 | shell_check_oom(a); |
| 25511 | memset(a, 0, sz); |
| 25512 | for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
| 25513 | int j = 0; /* Page number from "| page" line */ |
| 25514 | int k = 0; /* Offset from "| page" line */ |
| 25515 | rc = sscanf(zLine, "| page %d offset %d", &j, &k); |
| 25516 | if( rc==2 ){ |
| 25517 | iOffset = k; |
| 25518 | continue; |
| 25519 | } |
| @@ -25775,18 +25522,18 @@ | |
| 25522 | } |
| 25523 | rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", |
| 25524 | &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], |
| 25525 | &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); |
| 25526 | if( rc==17 ){ |
| 25527 | i64 iOff = iOffset+j; |
| 25528 | if( iOff+16<=sz && iOff>=0 ){ |
| 25529 | int ii; |
| 25530 | for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff; |
| 25531 | } |
| 25532 | } |
| 25533 | } |
| 25534 | *pnData = sz; |
| 25535 | if( in!=p->in ){ |
| 25536 | fclose(in); |
| 25537 | }else{ |
| 25538 | p->lineno = nLine; |
| 25539 | } |
| @@ -25849,11 +25596,11 @@ | |
| 25596 | p->pLog = pSavedLog; |
| 25597 | |
| 25598 | if( zFake ){ |
| 25599 | sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), |
| 25600 | -1, sqlite3_free); |
| 25601 | sqlite3_free(zFake); |
| 25602 | } |
| 25603 | } |
| 25604 | |
| 25605 | /* Flags for open_db(). |
| 25606 | ** |
| @@ -25881,14 +25628,17 @@ | |
| 25628 | }else{ |
| 25629 | p->openMode = (u8)deduceDatabaseType(zDbFilename, |
| 25630 | (openFlags & OPEN_DB_ZIPFILE)!=0); |
| 25631 | } |
| 25632 | } |
| 25633 | if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){ |
| 25634 | if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE; |
| 25635 | p->openFlags |= SQLITE_OPEN_READWRITE; |
| 25636 | } |
| 25637 | switch( p->openMode ){ |
| 25638 | case SHELL_OPEN_APPENDVFS: { |
| 25639 | sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, "apndvfs"); |
| 25640 | break; |
| 25641 | } |
| 25642 | case SHELL_OPEN_HEXDB: |
| 25643 | case SHELL_OPEN_DESERIALIZE: { |
| 25644 | sqlite3_open(0, &p->db); |
| @@ -25896,19 +25646,13 @@ | |
| 25646 | } |
| 25647 | case SHELL_OPEN_ZIPFILE: { |
| 25648 | sqlite3_open(":memory:", &p->db); |
| 25649 | break; |
| 25650 | } |
| 25651 | case SHELL_OPEN_UNSPEC: |
| 25652 | case SHELL_OPEN_NORMAL: { |
| 25653 | sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0); |
| 25654 | break; |
| 25655 | } |
| 25656 | } |
| 25657 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
| 25658 | sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
| @@ -25944,11 +25688,10 @@ | |
| 25688 | sqlite3_sha_init(p->db, 0, 0); |
| 25689 | sqlite3_shathree_init(p->db, 0, 0); |
| 25690 | sqlite3_uint_init(p->db, 0, 0); |
| 25691 | sqlite3_stmtrand_init(p->db, 0, 0); |
| 25692 | sqlite3_decimal_init(p->db, 0, 0); |
| 25693 | sqlite3_base64_init(p->db, 0, 0); |
| 25694 | sqlite3_base85_init(p->db, 0, 0); |
| 25695 | sqlite3_regexp_init(p->db, 0, 0); |
| 25696 | sqlite3_ieee_init(p->db, 0, 0); |
| 25697 | sqlite3_series_init(p->db, 0, 0); |
| @@ -26043,13 +25786,15 @@ | |
| 25786 | } |
| 25787 | } |
| 25788 | #endif |
| 25789 | } |
| 25790 | if( p->db!=0 ){ |
| 25791 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 25792 | if( p->bSafeModePersist ){ |
| 25793 | sqlite3_set_authorizer(p->db, safeModeAuth, p); |
| 25794 | } |
| 25795 | #endif |
| 25796 | sqlite3_db_config( |
| 25797 | p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0 |
| 25798 | ); |
| 25799 | } |
| 25800 | } |
| @@ -26358,12 +26103,12 @@ | |
| 26103 | struct ImportCtx { |
| 26104 | const char *zFile; /* Name of the input file */ |
| 26105 | FILE *in; /* Read the CSV text from this input stream */ |
| 26106 | int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */ |
| 26107 | char *z; /* Accumulated text for a field */ |
| 26108 | i64 n; /* Number of bytes in z */ |
| 26109 | i64 nAlloc; /* Space allocated for z[] */ |
| 26110 | int nLine; /* Current line number */ |
| 26111 | int nRow; /* Number of rows imported */ |
| 26112 | int nErr; /* Number of errors encountered */ |
| 26113 | int bNotFirst; /* True if one or more bytes already read */ |
| 26114 | int cTerm; /* Character that terminated the most recent field */ |
| @@ -26829,14 +26574,17 @@ | |
| 26574 | #if SQLITE_SHELL_HAVE_RECOVER |
| 26575 | /* |
| 26576 | ** Convert a 2-byte or 4-byte big-endian integer into a native integer |
| 26577 | */ |
| 26578 | static unsigned int get2byteInt(unsigned char *a){ |
| 26579 | return ((unsigned int)a[0]<<8) + (unsigned int)a[1]; |
| 26580 | } |
| 26581 | static unsigned int get4byteInt(unsigned char *a){ |
| 26582 | return ((unsigned int)a[0]<<24) |
| 26583 | + ((unsigned int)a[1]<<16) |
| 26584 | + ((unsigned int)a[2]<<8) |
| 26585 | + (unsigned int)a[3]; |
| 26586 | } |
| 26587 | |
| 26588 | /* |
| 26589 | ** Implementation of the ".dbinfo" command. |
| 26590 | ** |
| @@ -26969,11 +26717,11 @@ | |
| 26717 | if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; |
| 26718 | nPage = sqlite3_column_int64(pStmt, 0); |
| 26719 | sqlite3_finalize(pStmt); |
| 26720 | pStmt = 0; |
| 26721 | if( nPage<1 ) goto dbtotxt_error; |
| 26722 | rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); |
| 26723 | if( rc ) goto dbtotxt_error; |
| 26724 | if( sqlite3_step(pStmt)!=SQLITE_ROW ){ |
| 26725 | zTail = "unk.db"; |
| 26726 | }else{ |
| 26727 | const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2); |
| @@ -26980,10 +26728,15 @@ | |
| 26728 | if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; |
| 26729 | zTail = strrchr(zFilename, '/'); |
| 26730 | #if defined(_WIN32) |
| 26731 | if( zTail==0 ) zTail = strrchr(zFilename, '\\'); |
| 26732 | #endif |
| 26733 | if( zTail==0 ){ |
| 26734 | zTail = zFilename; |
| 26735 | }else if( zTail[1]!=0 ){ |
| 26736 | zTail++; |
| 26737 | } |
| 26738 | } |
| 26739 | zName = strdup(zTail); |
| 26740 | shell_check_oom(zName); |
| 26741 | sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", |
| 26742 | nPage*pgSz, pgSz, zName); |
| @@ -27148,10 +26901,47 @@ | |
| 26901 | if( zStr[0]!='-' ) return 0; |
| 26902 | zStr++; |
| 26903 | if( zStr[0]=='-' ) zStr++; |
| 26904 | return cli_strcmp(zStr, zOpt)==0; |
| 26905 | } |
| 26906 | |
| 26907 | /* |
| 26908 | ** The input zFN is guaranteed to start with "file:" and is thus a URI |
| 26909 | ** filename. Extract the actual filename and return a pointer to that |
| 26910 | ** filename in spaced obtained from sqlite3_malloc(). |
| 26911 | ** |
| 26912 | ** The caller is responsible for freeing space using sqlite3_free() when |
| 26913 | ** it has finished with the filename. |
| 26914 | */ |
| 26915 | static char *shellFilenameFromUri(const char *zFN){ |
| 26916 | char *zOut; |
| 26917 | int i, j, d1, d2; |
| 26918 | |
| 26919 | assert( cli_strncmp(zFN,"file:",5)==0 ); |
| 26920 | zOut = sqlite3_mprintf("%s", zFN+5); |
| 26921 | shell_check_oom(zOut); |
| 26922 | for(i=j=0; zOut[i]!=0 && zOut[i]!='?'; i++){ |
| 26923 | if( zOut[i]!='%' ){ |
| 26924 | zOut[j++] = zOut[i]; |
| 26925 | continue; |
| 26926 | } |
| 26927 | d1 = hexDigitValue(zOut[i+1]); |
| 26928 | if( d1<0 ){ |
| 26929 | zOut[j] = 0; |
| 26930 | break; |
| 26931 | } |
| 26932 | d2 = hexDigitValue(zOut[i+2]); |
| 26933 | if( d2<0 ){ |
| 26934 | zOut[j] = 0; |
| 26935 | break; |
| 26936 | } |
| 26937 | zOut[j++] = d1*16 + d2; |
| 26938 | i += 2; |
| 26939 | } |
| 26940 | zOut[j] = 0; |
| 26941 | return zOut; |
| 26942 | } |
| 26943 | |
| 26944 | /* |
| 26945 | ** Delete a file. |
| 26946 | */ |
| 26947 | int shellDeleteFile(const char *zFilename){ |
| @@ -28704,11 +28494,11 @@ | |
| 28494 | int nArg = 0; |
| 28495 | int n, c; |
| 28496 | int rc = 0; |
| 28497 | char *azArg[52]; |
| 28498 | |
| 28499 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 28500 | if( p->expert.pExpert ){ |
| 28501 | expertFinish(p, 1, 0); |
| 28502 | } |
| 28503 | #endif |
| 28504 | |
| @@ -29005,11 +28795,11 @@ | |
| 28795 | }else{ |
| 28796 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 28797 | const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); |
| 28798 | const char *zFile = (const char*)sqlite3_column_text(pStmt,2); |
| 28799 | if( zSchema==0 || zFile==0 ) continue; |
| 28800 | azName = sqlite3_realloc64(azName, (nName+1)*2*sizeof(char*)); |
| 28801 | shell_check_oom(azName); |
| 28802 | azName[nName*2] = strdup(zSchema); |
| 28803 | azName[nName*2+1] = strdup(zFile); |
| 28804 | nName++; |
| 28805 | } |
| @@ -29208,10 +28998,11 @@ | |
| 28998 | rc = 1; |
| 28999 | } |
| 29000 | }else |
| 29001 | |
| 29002 | if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ |
| 29003 | open_db(p, 0); |
| 29004 | rc = shell_dbtotxt_command(p, nArg, azArg); |
| 29005 | }else |
| 29006 | |
| 29007 | if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ |
| 29008 | if( nArg==2 ){ |
| @@ -29273,11 +29064,11 @@ | |
| 29064 | if( p->mode==MODE_Explain ) p->mode = p->normalMode; |
| 29065 | p->autoExplain = 1; |
| 29066 | } |
| 29067 | }else |
| 29068 | |
| 29069 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 29070 | if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ |
| 29071 | if( p->bSafeMode ){ |
| 29072 | sqlite3_fprintf(stderr, |
| 29073 | "Cannot run experimental commands such as \"%s\" in safe mode\n", |
| 29074 | azArg[0]); |
| @@ -29840,16 +29631,10 @@ | |
| 29631 | sqlite3_stmt *pStmt; |
| 29632 | int tnum = 0; |
| 29633 | int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ |
| 29634 | int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ |
| 29635 | int i; |
| 29636 | if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ |
| 29637 | eputz("Usage: .imposter INDEX IMPOSTER\n" |
| 29638 | " .imposter off\n"); |
| 29639 | /* Also allowed, but not documented: |
| 29640 | ** |
| @@ -29917,22 +29702,19 @@ | |
| 29702 | if( lenPK==0 ) lenPK = 100000; |
| 29703 | zSql = sqlite3_mprintf( |
| 29704 | "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID", |
| 29705 | azArg[2], zCollist, lenPK, zCollist); |
| 29706 | sqlite3_free(zCollist); |
| 29707 | rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum); |
| 29708 | if( rc==SQLITE_OK ){ |
| 29709 | rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
| 29710 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); |
| 29711 | if( rc ){ |
| 29712 | sqlite3_fprintf(stderr, |
| 29713 | "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); |
| 29714 | }else{ |
| 29715 | sqlite3_fprintf(stdout, "%s;\n", zSql); |
| 29716 | } |
| 29717 | }else{ |
| 29718 | sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); |
| 29719 | rc = 1; |
| 29720 | } |
| @@ -30282,10 +30064,11 @@ | |
| 30064 | const char *zFN = 0; /* Pointer to constant filename */ |
| 30065 | char *zNewFilename = 0; /* Name of the database file to open */ |
| 30066 | int iName = 1; /* Index in azArg[] of the filename */ |
| 30067 | int newFlag = 0; /* True to delete file before opening */ |
| 30068 | int openMode = SHELL_OPEN_UNSPEC; |
| 30069 | int openFlags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; |
| 30070 | |
| 30071 | /* Check for command-line arguments */ |
| 30072 | for(iName=1; iName<nArg; iName++){ |
| 30073 | const char *z = azArg[iName]; |
| 30074 | #ifndef SQLITE_SHELL_FIDDLE |
| @@ -30296,13 +30079,18 @@ | |
| 30079 | openMode = SHELL_OPEN_ZIPFILE; |
| 30080 | #endif |
| 30081 | }else if( optionMatch(z, "append") ){ |
| 30082 | openMode = SHELL_OPEN_APPENDVFS; |
| 30083 | }else if( optionMatch(z, "readonly") ){ |
| 30084 | openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 30085 | openFlags |= SQLITE_OPEN_READONLY; |
| 30086 | }else if( optionMatch(z, "exclusive") ){ |
| 30087 | openFlags |= SQLITE_OPEN_EXCLUSIVE; |
| 30088 | }else if( optionMatch(z, "ifexists") ){ |
| 30089 | openFlags &= ~(SQLITE_OPEN_CREATE); |
| 30090 | }else if( optionMatch(z, "nofollow") ){ |
| 30091 | openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 30092 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 30093 | }else if( optionMatch(z, "deserialize") ){ |
| 30094 | openMode = SHELL_OPEN_DESERIALIZE; |
| 30095 | }else if( optionMatch(z, "hexdb") ){ |
| 30096 | openMode = SHELL_OPEN_HEXDB; |
| @@ -30330,16 +30118,25 @@ | |
| 30118 | p->db = 0; |
| 30119 | p->pAuxDb->zDbFilename = 0; |
| 30120 | sqlite3_free(p->pAuxDb->zFreeOnClose); |
| 30121 | p->pAuxDb->zFreeOnClose = 0; |
| 30122 | p->openMode = openMode; |
| 30123 | p->openFlags = openFlags; |
| 30124 | p->szMax = 0; |
| 30125 | |
| 30126 | /* If a filename is specified, try to open it first */ |
| 30127 | if( zFN || p->openMode==SHELL_OPEN_HEXDB ){ |
| 30128 | if( newFlag && zFN && !p->bSafeMode ){ |
| 30129 | if( cli_strncmp(zFN,"file:",5)==0 ){ |
| 30130 | char *zDel = shellFilenameFromUri(zFN); |
| 30131 | shell_check_oom(zDel); |
| 30132 | shellDeleteFile(zDel); |
| 30133 | sqlite3_free(zDel); |
| 30134 | }else{ |
| 30135 | shellDeleteFile(zFN); |
| 30136 | } |
| 30137 | } |
| 30138 | #ifndef SQLITE_SHELL_FIDDLE |
| 30139 | if( p->bSafeMode |
| 30140 | && p->openMode!=SHELL_OPEN_HEXDB |
| 30141 | && zFN |
| 30142 | && cli_strcmp(zFN,":memory:")!=0 |
| @@ -30938,13 +30735,13 @@ | |
| 30735 | appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0); |
| 30736 | } |
| 30737 | appendText(&sSelect, "sql IS NOT NULL" |
| 30738 | " ORDER BY snum, rowid", 0); |
| 30739 | if( bDebug ){ |
| 30740 | sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt); |
| 30741 | }else{ |
| 30742 | rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg); |
| 30743 | } |
| 30744 | freeText(&sSelect); |
| 30745 | } |
| 30746 | if( zErrMsg ){ |
| 30747 | shellEmitError(zErrMsg); |
| @@ -31072,19 +30869,20 @@ | |
| 30869 | |
| 30870 | /* .session filter GLOB .... |
| 30871 | ** Set a list of GLOB patterns of table names to be excluded. |
| 30872 | */ |
| 30873 | if( cli_strcmp(azCmd[0], "filter")==0 ){ |
| 30874 | int ii; |
| 30875 | i64 nByte; |
| 30876 | if( nCmd<2 ) goto session_syntax_error; |
| 30877 | if( pAuxDb->nSession ){ |
| 30878 | for(ii=0; ii<pSession->nFilter; ii++){ |
| 30879 | sqlite3_free(pSession->azFilter[ii]); |
| 30880 | } |
| 30881 | sqlite3_free(pSession->azFilter); |
| 30882 | nByte = sizeof(pSession->azFilter[0])*(nCmd-1); |
| 30883 | pSession->azFilter = sqlite3_malloc64( nByte ); |
| 30884 | shell_check_oom( pSession->azFilter ); |
| 30885 | for(ii=1; ii<nCmd; ii++){ |
| 30886 | char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); |
| 30887 | shell_check_oom(x); |
| 30888 | } |
| @@ -31264,26 +31062,26 @@ | |
| 31062 | sqlite3_fprintf(p->out, "%s\n", zSql); |
| 31063 | }else |
| 31064 | if( cli_strcmp(zOp,"run")==0 ){ |
| 31065 | char *zErrMsg = 0; |
| 31066 | str.n = 0; |
| 31067 | str.zTxt[0] = 0; |
| 31068 | rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); |
| 31069 | nTest++; |
| 31070 | if( bVerbose ){ |
| 31071 | sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt); |
| 31072 | } |
| 31073 | if( rc || zErrMsg ){ |
| 31074 | nErr++; |
| 31075 | rc = 1; |
| 31076 | sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); |
| 31077 | sqlite3_free(zErrMsg); |
| 31078 | }else if( cli_strcmp(zAns,str.zTxt)!=0 ){ |
| 31079 | nErr++; |
| 31080 | rc = 1; |
| 31081 | sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); |
| 31082 | sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt); |
| 31083 | } |
| 31084 | } |
| 31085 | else{ |
| 31086 | sqlite3_fprintf(stderr, |
| 31087 | "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); |
| @@ -31395,11 +31193,11 @@ | |
| 31193 | appendText(&sQuery, "SELECT * FROM ", 0); |
| 31194 | appendText(&sQuery, zTab, 0); |
| 31195 | appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); |
| 31196 | } |
| 31197 | appendText(&sSql, zSep, 0); |
| 31198 | appendText(&sSql, sQuery.zTxt, '\''); |
| 31199 | sQuery.n = 0; |
| 31200 | appendText(&sSql, ",", 0); |
| 31201 | appendText(&sSql, zTab, '\''); |
| 31202 | zSep = "),("; |
| 31203 | } |
| @@ -31407,17 +31205,17 @@ | |
| 31205 | if( bSeparate ){ |
| 31206 | zSql = sqlite3_mprintf( |
| 31207 | "%s))" |
| 31208 | " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" |
| 31209 | " FROM [sha3sum$query]", |
| 31210 | sSql.zTxt, iSize); |
| 31211 | }else{ |
| 31212 | zSql = sqlite3_mprintf( |
| 31213 | "%s))" |
| 31214 | " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" |
| 31215 | " FROM [sha3sum$query]", |
| 31216 | sSql.zTxt, iSize); |
| 31217 | } |
| 31218 | shell_check_oom(zSql); |
| 31219 | freeText(&sQuery); |
| 31220 | freeText(&sSql); |
| 31221 | if( bDebug ){ |
| @@ -31613,11 +31411,11 @@ | |
| 31411 | goto meta_command_exit; |
| 31412 | } |
| 31413 | for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ |
| 31414 | const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); |
| 31415 | if( zDbName==0 ) continue; |
| 31416 | if( s.zTxt && s.zTxt[0] ) appendText(&s, " UNION ALL ", 0); |
| 31417 | if( sqlite3_stricmp(zDbName, "main")==0 ){ |
| 31418 | appendText(&s, "SELECT name FROM ", 0); |
| 31419 | }else{ |
| 31420 | appendText(&s, "SELECT ", 0); |
| 31421 | appendText(&s, zDbName, '\''); |
| @@ -31635,11 +31433,11 @@ | |
| 31433 | } |
| 31434 | } |
| 31435 | rc = sqlite3_finalize(pStmt); |
| 31436 | if( rc==SQLITE_OK ){ |
| 31437 | appendText(&s, " ORDER BY 1", 0); |
| 31438 | rc = sqlite3_prepare_v2(p->db, s.zTxt, -1, &pStmt, 0); |
| 31439 | } |
| 31440 | freeText(&s); |
| 31441 | if( rc ) return shellDatabaseError(p->db); |
| 31442 | |
| 31443 | /* Run the SQL statement prepared by the above block. Store the results |
| @@ -31652,14 +31450,14 @@ | |
| 31450 | sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); |
| 31451 | } |
| 31452 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 31453 | if( nRow>=nAlloc ){ |
| 31454 | char **azNew; |
| 31455 | sqlite3_int64 n2 = 2*(sqlite3_int64)nAlloc + 10; |
| 31456 | azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); |
| 31457 | shell_check_oom(azNew); |
| 31458 | nAlloc = (int)n2; |
| 31459 | azResult = azNew; |
| 31460 | } |
| 31461 | azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); |
| 31462 | shell_check_oom(azResult[nRow]); |
| 31463 | nRow++; |
| @@ -31818,11 +31616,11 @@ | |
| 31616 | { 0x00000020, 1, "CoverIdxScan" }, |
| 31617 | { 0x00000040, 1, "OrderByIdxJoin" }, |
| 31618 | { 0x00000080, 1, "Transitive" }, |
| 31619 | { 0x00000100, 1, "OmitNoopJoin" }, |
| 31620 | { 0x00000200, 1, "CountOfView" }, |
| 31621 | { 0x00000400, 1, "CursorHints" }, |
| 31622 | { 0x00000800, 1, "Stat4" }, |
| 31623 | { 0x00001000, 1, "PushDown" }, |
| 31624 | { 0x00002000, 1, "SimplifyJoin" }, |
| 31625 | { 0x00004000, 1, "SkipScan" }, |
| 31626 | { 0x00008000, 1, "PropagateConst" }, |
| @@ -32365,11 +32163,14 @@ | |
| 32163 | p->nWidth = nArg-1; |
| 32164 | p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2); |
| 32165 | if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory(); |
| 32166 | if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth]; |
| 32167 | for(j=1; j<nArg; j++){ |
| 32168 | i64 w = integerValue(azArg[j]); |
| 32169 | if( w < -30000 ) w = -30000; |
| 32170 | if( w > +30000 ) w = +30000; |
| 32171 | p->colWidth[j-1] = (int)w; |
| 32172 | } |
| 32173 | }else |
| 32174 | |
| 32175 | { |
| 32176 | sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " |
| @@ -32888,76 +32689,95 @@ | |
| 32689 | |
| 32690 | return home_dir; |
| 32691 | } |
| 32692 | |
| 32693 | /* |
| 32694 | ** On non-Windows platforms, look for: |
| 32695 | ** |
| 32696 | ** - ${zEnvVar}/${zBaseName} |
| 32697 | ** - ${HOME}/${zSubdir}/${zBaseName} |
| 32698 | ** |
| 32699 | ** $zEnvVar is intended to be the name of an XDG_... environment |
| 32700 | ** variable, e.g. XDG_CONFIG_HOME or XDG_STATE_HOME. If zEnvVar is |
| 32701 | ** NULL or getenv(zEnvVar) is NULL then fall back to the second |
| 32702 | ** option. If the selected option is not found in the filesystem, |
| 32703 | ** return 0. |
| 32704 | ** |
| 32705 | ** zSubdir may be NULL or empty, in which case ${HOME}/${zBaseName} |
| 32706 | ** becomes the fallback. |
| 32707 | ** |
| 32708 | ** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir |
| 32709 | ** will conventionally be ".config" or ".local/state", which, not |
| 32710 | ** coincidentally, is the typical subdir of the corresponding XDG_... |
| 32711 | ** var with the XDG var's $HOME prefix. |
| 32712 | ** |
| 32713 | ** The returned string is obtained from sqlite3_malloc() and should be |
| 32714 | ** sqlite3_free()'d by the caller. |
| 32715 | */ |
| 32716 | static char *find_xdg_file(const char *zEnvVar, const char *zSubdir, |
| 32717 | const char *zBaseName){ |
| 32718 | #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ |
| 32719 | || defined(__RTP__) || defined(_WRS_KERNEL) |
| 32720 | return 0; |
| 32721 | #else |
| 32722 | char *zConfigFile = 0; |
| 32723 | const char *zXdgDir; |
| 32724 | |
| 32725 | zXdgDir = zEnvVar ? getenv(zEnvVar) : 0; |
| 32726 | if( zXdgDir ){ |
| 32727 | zConfigFile = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName); |
| 32728 | }else{ |
| 32729 | const char * zHome = find_home_dir(0); |
| 32730 | if( zHome==0 ) return 0; |
| 32731 | zConfigFile = (zSubdir && *zSubdir) |
| 32732 | ? sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName) |
| 32733 | : sqlite3_mprintf("%s/%s", zHome, zBaseName); |
| 32734 | } |
| 32735 | shell_check_oom(zConfigFile); |
| 32736 | if( access(zConfigFile,0)!=0 ){ |
| 32737 | sqlite3_free(zConfigFile); |
| 32738 | zConfigFile = 0; |
| 32739 | } |
| 32740 | return zConfigFile; |
| 32741 | #endif |
| 32742 | } |
| 32743 | |
| 32744 | /* |
| 32745 | ** Read input from the file sqliterc_override. If that parameter is |
| 32746 | ** NULL, take it from find_xdg_file(), if found, or fall back to |
| 32747 | ** ~/.sqliterc. |
| 32748 | ** |
| 32749 | ** Failure to read the config is only considered a failure if |
| 32750 | ** sqliterc_override is not NULL, in which case this function may emit |
| 32751 | ** a warning or, if ::bail_on_error is true, fail fatally if the file |
| 32752 | ** named by sqliterc_override is not found. |
| 32753 | */ |
| 32754 | static void process_sqliterc( |
| 32755 | ShellState *p, /* Configuration data */ |
| 32756 | const char *sqliterc_override /* Name of config file. NULL to use default */ |
| 32757 | ){ |
| 32758 | char *home_dir = NULL; |
| 32759 | char *sqliterc = (char*)sqliterc_override; |
| 32760 | FILE *inSaved = p->in; |
| 32761 | int savedLineno = p->lineno; |
| 32762 | |
| 32763 | if( sqliterc == NULL ){ |
| 32764 | sqliterc = find_xdg_file("XDG_CONFIG_HOME", |
| 32765 | ".config", |
| 32766 | "sqlite3/sqliterc"); |
| 32767 | } |
| 32768 | if( sqliterc == NULL ){ |
| 32769 | home_dir = find_home_dir(0); |
| 32770 | if( home_dir==0 ){ |
| 32771 | eputz("-- warning: cannot find home directory;" |
| 32772 | " cannot read ~/.sqliterc\n"); |
| 32773 | return; |
| 32774 | } |
| 32775 | sqliterc = sqlite3_mprintf("%s/.sqliterc",home_dir); |
| 32776 | shell_check_oom(sqliterc); |
| 32777 | } |
| 32778 | p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0; |
| 32779 | if( p->in ){ |
| 32780 | if( stdin_is_interactive ){ |
| 32781 | sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); |
| 32782 | } |
| 32783 | if( process_input(p) && bail_on_error ) exit(1); |
| @@ -32966,11 +32786,13 @@ | |
| 32786 | sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); |
| 32787 | if( bail_on_error ) exit(1); |
| 32788 | } |
| 32789 | p->in = inSaved; |
| 32790 | p->lineno = savedLineno; |
| 32791 | if( sqliterc != sqliterc_override ){ |
| 32792 | sqlite3_free(sqliterc); |
| 32793 | } |
| 32794 | } |
| 32795 | |
| 32796 | /* |
| 32797 | ** Show available command line options |
| 32798 | */ |
| @@ -32997,10 +32819,11 @@ | |
| 32819 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
| 32820 | " -heap SIZE Size of heap for memsys3 or memsys5\n" |
| 32821 | #endif |
| 32822 | " -help show this message\n" |
| 32823 | " -html set output mode to HTML\n" |
| 32824 | " -ifexists only open if database already exists\n" |
| 32825 | " -interactive force interactive I/O\n" |
| 32826 | " -json set output mode to 'json'\n" |
| 32827 | " -line set output mode to 'line'\n" |
| 32828 | " -list set output mode to 'list'\n" |
| 32829 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| @@ -33341,16 +33164,24 @@ | |
| 33164 | (void)cmdline_option_value(argc, argv, ++i); |
| 33165 | #endif |
| 33166 | }else if( cli_strcmp(z,"-pagecache")==0 ){ |
| 33167 | sqlite3_int64 n, sz; |
| 33168 | sz = integerValue(cmdline_option_value(argc,argv,++i)); |
| 33169 | if( sz>65536 ) sz = 65536; |
| 33170 | if( sz<0 ) sz = 0; |
| 33171 | n = integerValue(cmdline_option_value(argc,argv,++i)); |
| 33172 | if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){ |
| 33173 | n = 0xffffffffffffLL/sz; |
| 33174 | } |
| 33175 | if( sz>0 && (sz & (sz-1))==0 ){ |
| 33176 | /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */ |
| 33177 | int szHdr = 0; |
| 33178 | sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr); |
| 33179 | sz += szHdr; |
| 33180 | sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate" |
| 33181 | " the %d-byte headers\n", (int)sz, szHdr); |
| 33182 | } |
| 33183 | verify_uninitialized(); |
| 33184 | sqlite3_config(SQLITE_CONFIG_PAGECACHE, |
| 33185 | (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); |
| 33186 | data.shellFlgs |= SHFLG_Pagecache; |
| 33187 | }else if( cli_strcmp(z,"-lookaside")==0 ){ |
| @@ -33359,11 +33190,11 @@ | |
| 33190 | if( sz<0 ) sz = 0; |
| 33191 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
| 33192 | if( n<0 ) n = 0; |
| 33193 | verify_uninitialized(); |
| 33194 | sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); |
| 33195 | if( (i64)sz*(i64)n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; |
| 33196 | }else if( cli_strcmp(z,"-threadsafe")==0 ){ |
| 33197 | int n; |
| 33198 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
| 33199 | verify_uninitialized(); |
| 33200 | switch( n ){ |
| @@ -33401,13 +33232,19 @@ | |
| 33232 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33233 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33234 | data.szMax = integerValue(argv[++i]); |
| 33235 | #endif |
| 33236 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33237 | data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 33238 | data.openFlags |= SQLITE_OPEN_READONLY; |
| 33239 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33240 | data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 33241 | }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ |
| 33242 | data.openFlags |= SQLITE_OPEN_EXCLUSIVE; |
| 33243 | }else if( cli_strcmp(z,"-ifexists")==0 ){ |
| 33244 | data.openFlags &= ~(SQLITE_OPEN_CREATE); |
| 33245 | if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; |
| 33246 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
| 33247 | }else if( cli_strncmp(z, "-A",2)==0 ){ |
| 33248 | /* All remaining command-line arguments are passed to the ".archive" |
| 33249 | ** command, so ignore them */ |
| 33250 | break; |
| @@ -33557,13 +33394,19 @@ | |
| 33394 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33395 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33396 | data.szMax = integerValue(argv[++i]); |
| 33397 | #endif |
| 33398 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33399 | data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 33400 | data.openFlags |= SQLITE_OPEN_READONLY; |
| 33401 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33402 | data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 33403 | }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ |
| 33404 | data.openFlags |= SQLITE_OPEN_EXCLUSIVE; |
| 33405 | }else if( cli_strcmp(z,"-ifexists")==0 ){ |
| 33406 | data.openFlags &= ~(SQLITE_OPEN_CREATE); |
| 33407 | if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; |
| 33408 | }else if( cli_strcmp(z,"-ascii")==0 ){ |
| 33409 | data.mode = MODE_Ascii; |
| 33410 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit); |
| 33411 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record); |
| 33412 | }else if( cli_strcmp(z,"-tabs")==0 ){ |
| @@ -33734,11 +33577,10 @@ | |
| 33577 | /* Run commands received from standard input |
| 33578 | */ |
| 33579 | if( stdin_is_interactive ){ |
| 33580 | char *zHome; |
| 33581 | char *zHistory; |
| 33582 | sqlite3_fprintf(stdout, |
| 33583 | "SQLite version %s %.19s\n" /*extra-version-info*/ |
| 33584 | "Enter \".help\" for usage hints.\n", |
| 33585 | sqlite3_libversion(), sqlite3_sourceid()); |
| 33586 | if( warnInmemoryDb ){ |
| @@ -33747,15 +33589,19 @@ | |
| 33589 | sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a" |
| 33590 | " persistent database.\n"); |
| 33591 | } |
| 33592 | zHistory = getenv("SQLITE_HISTORY"); |
| 33593 | if( zHistory ){ |
| 33594 | zHistory = sqlite3_mprintf("%s", zHistory); |
| 33595 | shell_check_oom(zHistory); |
| 33596 | }else{ |
| 33597 | zHistory = find_xdg_file("XDG_STATE_HOME", |
| 33598 | ".local/state", |
| 33599 | "sqlite_history"); |
| 33600 | if( 0==zHistory && (zHome = find_home_dir(0))!=0 ){ |
| 33601 | zHistory = sqlite3_mprintf("%s/.sqlite_history", zHome); |
| 33602 | shell_check_oom(zHistory); |
| 33603 | } |
| 33604 | } |
| 33605 | if( zHistory ){ shell_read_history(zHistory); } |
| 33606 | #if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) |
| 33607 | rl_attempted_completion_function = readline_completion; |
| @@ -33767,21 +33613,21 @@ | |
| 33613 | data.in = 0; |
| 33614 | rc = process_input(&data); |
| 33615 | if( zHistory ){ |
| 33616 | shell_stifle_history(2000); |
| 33617 | shell_write_history(zHistory); |
| 33618 | sqlite3_free(zHistory); |
| 33619 | } |
| 33620 | }else{ |
| 33621 | data.in = stdin; |
| 33622 | rc = process_input(&data); |
| 33623 | } |
| 33624 | } |
| 33625 | #ifndef SQLITE_SHELL_FIDDLE |
| 33626 | /* In WASM mode we have to leave the db state in place so that |
| 33627 | ** client code can "push" SQL into it after this call returns. */ |
| 33628 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 33629 | if( data.expert.pExpert ){ |
| 33630 | expertFinish(&data, 1, 0); |
| 33631 | } |
| 33632 | #endif |
| 33633 | shell_main_exit: |
| 33634 |
+2521
-708
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -16,11 +16,11 @@ | ||
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | -** 9f184f8dfa5ef6d57e10376adc30e0060ced with changes in files: | |
| 21 | +** 5cbccab499bc3983aac1f57355552db607de with changes in files: | |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| @@ -168,11 +168,13 @@ | ||
| 168 | 168 | #define SQLITE_OMIT_LOAD_EXTENSION 1 |
| 169 | 169 | #define SQLITE_ENABLE_LOCKING_STYLE 0 |
| 170 | 170 | #define HAVE_UTIME 1 |
| 171 | 171 | #else |
| 172 | 172 | /* This is not VxWorks. */ |
| 173 | -#define OS_VXWORKS 0 | |
| 173 | +#ifndef OS_VXWORKS | |
| 174 | +# define OS_VXWORKS 0 | |
| 175 | +#endif | |
| 174 | 176 | #define HAVE_FCHOWN 1 |
| 175 | 177 | #define HAVE_READLINK 1 |
| 176 | 178 | #define HAVE_LSTAT 1 |
| 177 | 179 | #endif /* defined(_WRS_KERNEL) */ |
| 178 | 180 | |
| @@ -465,11 +467,14 @@ | ||
| 465 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 469 | */ |
| 468 | 470 | #define SQLITE_VERSION "3.51.0" |
| 469 | 471 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | -#define SQLITE_SOURCE_ID "2025-07-15 19:00:01 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839" | |
| 472 | +#define SQLITE_SOURCE_ID "2025-10-15 10:52:45 5cbccab499bc3983aac1f57355552db607dee6c7ef4eb00d794dbee89c18db70" | |
| 473 | +#define SQLITE_SCM_BRANCH "trunk" | |
| 474 | +#define SQLITE_SCM_TAGS "" | |
| 475 | +#define SQLITE_SCM_DATETIME "2025-10-15T10:52:45.276Z" | |
| 471 | 476 | |
| 472 | 477 | /* |
| 473 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 480 | ** |
| @@ -814,10 +819,13 @@ | ||
| 814 | 819 | ** [sqlite3_extended_errcode()]. |
| 815 | 820 | */ |
| 816 | 821 | #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) |
| 817 | 822 | #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) |
| 818 | 823 | #define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) |
| 824 | +#define SQLITE_ERROR_RESERVESIZE (SQLITE_ERROR | (4<<8)) | |
| 825 | +#define SQLITE_ERROR_KEY (SQLITE_ERROR | (5<<8)) | |
| 826 | +#define SQLITE_ERROR_UNABLE (SQLITE_ERROR | (6<<8)) | |
| 819 | 827 | #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) |
| 820 | 828 | #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) |
| 821 | 829 | #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) |
| 822 | 830 | #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) |
| 823 | 831 | #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) |
| @@ -848,10 +856,12 @@ | ||
| 848 | 856 | #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) |
| 849 | 857 | #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) |
| 850 | 858 | #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) |
| 851 | 859 | #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) |
| 852 | 860 | #define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) |
| 861 | +#define SQLITE_IOERR_BADKEY (SQLITE_IOERR | (35<<8)) | |
| 862 | +#define SQLITE_IOERR_CODEC (SQLITE_IOERR | (36<<8)) | |
| 853 | 863 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 854 | 864 | #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) |
| 855 | 865 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 856 | 866 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 857 | 867 | #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8)) |
| @@ -2652,21 +2662,24 @@ | ||
| 2652 | 2662 | ** views in the main database schema or in the schemas of ATTACH-ed |
| 2653 | 2663 | ** databases.)^ </dd> |
| 2654 | 2664 | ** |
| 2655 | 2665 | ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] |
| 2656 | 2666 | ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> |
| 2657 | -** <dd> ^This option is used to enable or disable the | |
| 2658 | -** [fts3_tokenizer()] function which is part of the | |
| 2659 | -** [FTS3] full-text search engine extension. | |
| 2660 | -** There must be two additional arguments. | |
| 2661 | -** The first argument is an integer which is 0 to disable fts3_tokenizer() or | |
| 2662 | -** positive to enable fts3_tokenizer() or negative to leave the setting | |
| 2663 | -** unchanged. | |
| 2664 | -** The second parameter is a pointer to an integer into which | |
| 2665 | -** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled | |
| 2666 | -** following this call. The second parameter may be a NULL pointer, in | |
| 2667 | -** which case the new setting is not reported back. </dd> | |
| 2667 | +** <dd> ^This option is used to enable or disable using the | |
| 2668 | +** [fts3_tokenizer()] function - part of the [FTS3] full-text search engine | |
| 2669 | +** extension - without using bound parameters as the parameters. Doing so | |
| 2670 | +** is disabled by default. There must be two additional arguments. The first | |
| 2671 | +** argument is an integer. If it is passed 0, then using fts3_tokenizer() | |
| 2672 | +** without bound parameters is disabled. If it is passed a positive value, | |
| 2673 | +** then calling fts3_tokenizer without bound parameters is enabled. If it | |
| 2674 | +** is passed a negative value, this setting is not modified - this can be | |
| 2675 | +** used to query for the current setting. The second parameter is a pointer | |
| 2676 | +** to an integer into which is written 0 or 1 to indicate the current value | |
| 2677 | +** of this setting (after it is modified, if applicable). The second | |
| 2678 | +** parameter may be a NULL pointer, in which case the value of the setting | |
| 2679 | +** is not reported back. Refer to [FTS3] documentation for further details. | |
| 2680 | +** </dd> | |
| 2668 | 2681 | ** |
| 2669 | 2682 | ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] |
| 2670 | 2683 | ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt> |
| 2671 | 2684 | ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()] |
| 2672 | 2685 | ** interface independently of the [load_extension()] SQL function. |
| @@ -4512,10 +4525,38 @@ | ||
| 4512 | 4525 | SQLITE_API const char *sqlite3_errmsg(sqlite3*); |
| 4513 | 4526 | SQLITE_API const void *sqlite3_errmsg16(sqlite3*); |
| 4514 | 4527 | SQLITE_API const char *sqlite3_errstr(int); |
| 4515 | 4528 | SQLITE_API int sqlite3_error_offset(sqlite3 *db); |
| 4516 | 4529 | |
| 4530 | +/* | |
| 4531 | +** CAPI3REF: Set Error Codes And Message | |
| 4532 | +** METHOD: sqlite3 | |
| 4533 | +** | |
| 4534 | +** Set the error code of the database handle passed as the first argument | |
| 4535 | +** to errcode, and the error message to a copy of nul-terminated string | |
| 4536 | +** zErrMsg. If zErrMsg is passed NULL, then the error message is set to | |
| 4537 | +** the default message associated with the supplied error code. Subsequent | |
| 4538 | +** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will | |
| 4539 | +** return the values set by this routine in place of what was previously | |
| 4540 | +** set by SQLite itself. | |
| 4541 | +** | |
| 4542 | +** This function returns SQLITE_OK if the error code and error message are | |
| 4543 | +** successfully set, SQLITE_NOMEM if an OOM occurs, and SQLITE_MISUSE if | |
| 4544 | +** the database handle is NULL or invalid. | |
| 4545 | +** | |
| 4546 | +** The error code and message set by this routine remains in effect until | |
| 4547 | +** they are changed, either by another call to this routine or until they are | |
| 4548 | +** changed to by SQLite itself to reflect the result of some subsquent | |
| 4549 | +** API call. | |
| 4550 | +** | |
| 4551 | +** This function is intended for use by SQLite extensions or wrappers. The | |
| 4552 | +** idea is that an extension or wrapper can use this routine to set error | |
| 4553 | +** messages and error codes and thus behave more like a core SQLite | |
| 4554 | +** feature from the point of view of an application. | |
| 4555 | +*/ | |
| 4556 | +SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zErrMsg); | |
| 4557 | + | |
| 4517 | 4558 | /* |
| 4518 | 4559 | ** CAPI3REF: Prepared Statement Object |
| 4519 | 4560 | ** KEYWORDS: {prepared statement} {prepared statements} |
| 4520 | 4561 | ** |
| 4521 | 4562 | ** An instance of this object represents a single SQL statement that |
| @@ -6522,10 +6563,11 @@ | ||
| 6522 | 6563 | ** to be attached to [database connection] D using name N. Subsequent |
| 6523 | 6564 | ** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P |
| 6524 | 6565 | ** or a NULL pointer if there were no prior calls to |
| 6525 | 6566 | ** sqlite3_set_clientdata() with the same values of D and N. |
| 6526 | 6567 | ** Names are compared using strcmp() and are thus case sensitive. |
| 6568 | +** It returns 0 on success and SQLITE_NOMEM on allocation failure. | |
| 6527 | 6569 | ** |
| 6528 | 6570 | ** If P and X are both non-NULL, then the destructor X is invoked with |
| 6529 | 6571 | ** argument P on the first of the following occurrences: |
| 6530 | 6572 | ** <ul> |
| 6531 | 6573 | ** <li> An out-of-memory error occurs during the call to |
| @@ -9197,14 +9239,23 @@ | ||
| 9197 | 9239 | ** the resetFlg is true, then the highest instantaneous value is |
| 9198 | 9240 | ** reset back down to the current value. |
| 9199 | 9241 | ** |
| 9200 | 9242 | ** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a |
| 9201 | 9243 | ** non-zero [error code] on failure. |
| 9244 | +** | |
| 9245 | +** ^The sqlite3_db_status64(D,O,C,H,R) routine works exactly the same | |
| 9246 | +** way as sqlite3_db_status(D,O,C,H,R) routine except that the C and H | |
| 9247 | +** parameters are pointer to 64-bit integers (type: sqlite3_int64) instead | |
| 9248 | +** of pointers to 32-bit integers, which allows larger status values | |
| 9249 | +** to be returned. If a status value exceeds 2,147,483,647 then | |
| 9250 | +** sqlite3_db_status() will truncate the value whereas sqlite3_db_status64() | |
| 9251 | +** will return the full value. | |
| 9202 | 9252 | ** |
| 9203 | 9253 | ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. |
| 9204 | 9254 | */ |
| 9205 | 9255 | SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); |
| 9256 | +SQLITE_API int sqlite3_db_status64(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); | |
| 9206 | 9257 | |
| 9207 | 9258 | /* |
| 9208 | 9259 | ** CAPI3REF: Status Parameters for database connections |
| 9209 | 9260 | ** KEYWORDS: {SQLITE_DBSTATUS options} |
| 9210 | 9261 | ** |
| @@ -9297,10 +9348,14 @@ | ||
| 9297 | 9348 | ** database file in rollback mode databases. Any pages written as part of |
| 9298 | 9349 | ** transaction rollback or database recovery operations are not included. |
| 9299 | 9350 | ** If an IO or other error occurs while writing a page to disk, the effect |
| 9300 | 9351 | ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The |
| 9301 | 9352 | ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. |
| 9353 | +** <p> | |
| 9354 | +** ^(There is overlap between the quantities measured by this parameter | |
| 9355 | +** (SQLITE_DBSTATUS_CACHE_WRITE) and SQLITE_DBSTATUS_TEMPBUF_SPILL. | |
| 9356 | +** Resetting one will reduce the other.)^ | |
| 9302 | 9357 | ** </dd> |
| 9303 | 9358 | ** |
| 9304 | 9359 | ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> |
| 9305 | 9360 | ** <dd>This parameter returns the number of dirty cache entries that have |
| 9306 | 9361 | ** been written to disk in the middle of a transaction due to the page |
| @@ -9312,10 +9367,22 @@ | ||
| 9312 | 9367 | ** |
| 9313 | 9368 | ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> |
| 9314 | 9369 | ** <dd>This parameter returns zero for the current value if and only if |
| 9315 | 9370 | ** all foreign key constraints (deferred or immediate) have been |
| 9316 | 9371 | ** resolved.)^ ^The highwater mark is always 0. |
| 9372 | +** | |
| 9373 | +** [[SQLITE_DBSTATUS_TEMPBUF_SPILL] ^(<dt>SQLITE_DBSTATUS_TEMPBUF_SPILL</dt> | |
| 9374 | +** <dd>^(This parameter returns the number of bytes written to temporary | |
| 9375 | +** files on disk that could have been kept in memory had sufficient memory | |
| 9376 | +** been available. This value includes writes to intermediate tables that | |
| 9377 | +** are part of complex queries, external sorts that spill to disk, and | |
| 9378 | +** writes to TEMP tables.)^ | |
| 9379 | +** ^The highwater mark is always 0. | |
| 9380 | +** <p> | |
| 9381 | +** ^(There is overlap between the quantities measured by this parameter | |
| 9382 | +** (SQLITE_DBSTATUS_TEMPBUF_SPILL) and SQLITE_DBSTATUS_CACHE_WRITE. | |
| 9383 | +** Resetting one will reduce the other.)^ | |
| 9317 | 9384 | ** </dd> |
| 9318 | 9385 | ** </dl> |
| 9319 | 9386 | */ |
| 9320 | 9387 | #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 |
| 9321 | 9388 | #define SQLITE_DBSTATUS_CACHE_USED 1 |
| @@ -9328,11 +9395,12 @@ | ||
| 9328 | 9395 | #define SQLITE_DBSTATUS_CACHE_MISS 8 |
| 9329 | 9396 | #define SQLITE_DBSTATUS_CACHE_WRITE 9 |
| 9330 | 9397 | #define SQLITE_DBSTATUS_DEFERRED_FKS 10 |
| 9331 | 9398 | #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 |
| 9332 | 9399 | #define SQLITE_DBSTATUS_CACHE_SPILL 12 |
| 9333 | -#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */ | |
| 9400 | +#define SQLITE_DBSTATUS_TEMPBUF_SPILL 13 | |
| 9401 | +#define SQLITE_DBSTATUS_MAX 13 /* Largest defined DBSTATUS */ | |
| 9334 | 9402 | |
| 9335 | 9403 | |
| 9336 | 9404 | /* |
| 9337 | 9405 | ** CAPI3REF: Prepared Statement Status |
| 9338 | 9406 | ** METHOD: sqlite3_stmt |
| @@ -10093,25 +10161,38 @@ | ||
| 10093 | 10161 | ** ^The third parameter is the name of the database that was written to - |
| 10094 | 10162 | ** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter |
| 10095 | 10163 | ** is the number of pages currently in the write-ahead log file, |
| 10096 | 10164 | ** including those that were just committed. |
| 10097 | 10165 | ** |
| 10098 | -** The callback function should normally return [SQLITE_OK]. ^If an error | |
| 10166 | +** ^The callback function should normally return [SQLITE_OK]. ^If an error | |
| 10099 | 10167 | ** code is returned, that error will propagate back up through the |
| 10100 | 10168 | ** SQLite code base to cause the statement that provoked the callback |
| 10101 | 10169 | ** to report an error, though the commit will have still occurred. If the |
| 10102 | 10170 | ** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value |
| 10103 | 10171 | ** that does not correspond to any valid SQLite error code, the results |
| 10104 | 10172 | ** are undefined. |
| 10105 | 10173 | ** |
| 10106 | -** A single database handle may have at most a single write-ahead log callback | |
| 10107 | -** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any | |
| 10108 | -** previously registered write-ahead log callback. ^The return value is | |
| 10109 | -** a copy of the third parameter from the previous call, if any, or 0. | |
| 10110 | -** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the | |
| 10111 | -** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will | |
| 10112 | -** overwrite any prior [sqlite3_wal_hook()] settings. | |
| 10174 | +** ^A single database handle may have at most a single write-ahead log | |
| 10175 | +** callback registered at one time. ^Calling [sqlite3_wal_hook()] | |
| 10176 | +** replaces the default behavior or previously registered write-ahead | |
| 10177 | +** log callback. | |
| 10178 | +** | |
| 10179 | +** ^The return value is a copy of the third parameter from the | |
| 10180 | +** previous call, if any, or 0. | |
| 10181 | +** | |
| 10182 | +** ^The [sqlite3_wal_autocheckpoint()] interface and the | |
| 10183 | +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and | |
| 10184 | +** will overwrite any prior [sqlite3_wal_hook()] settings. | |
| 10185 | +** | |
| 10186 | +** ^If a write-ahead log callback is set using this function then | |
| 10187 | +** [sqlite3_wal_checkpoint_v2()] or [PRAGMA wal_checkpoint] | |
| 10188 | +** should be invoked periodically to keep the write-ahead log file | |
| 10189 | +** from growing without bound. | |
| 10190 | +** | |
| 10191 | +** ^Passing a NULL pointer for the callback disables automatic | |
| 10192 | +** checkpointing entirely. To re-enable the default behavior, call | |
| 10193 | +** sqlite3_wal_autocheckpoint(db,1000) or use [PRAGMA wal_checkpoint]. | |
| 10113 | 10194 | */ |
| 10114 | 10195 | SQLITE_API void *sqlite3_wal_hook( |
| 10115 | 10196 | sqlite3*, |
| 10116 | 10197 | int(*)(void *,sqlite3*,const char*,int), |
| 10117 | 10198 | void* |
| @@ -10124,11 +10205,11 @@ | ||
| 10124 | 10205 | ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around |
| 10125 | 10206 | ** [sqlite3_wal_hook()] that causes any database on [database connection] D |
| 10126 | 10207 | ** to automatically [checkpoint] |
| 10127 | 10208 | ** after committing a transaction if there are N or |
| 10128 | 10209 | ** more frames in the [write-ahead log] file. ^Passing zero or |
| 10129 | -** a negative value as the nFrame parameter disables automatic | |
| 10210 | +** a negative value as the N parameter disables automatic | |
| 10130 | 10211 | ** checkpoints entirely. |
| 10131 | 10212 | ** |
| 10132 | 10213 | ** ^The callback registered by this function replaces any existing callback |
| 10133 | 10214 | ** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback |
| 10134 | 10215 | ** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism |
| @@ -10140,13 +10221,14 @@ | ||
| 10140 | 10221 | ** ^Checkpoints initiated by this mechanism are |
| 10141 | 10222 | ** [sqlite3_wal_checkpoint_v2|PASSIVE]. |
| 10142 | 10223 | ** |
| 10143 | 10224 | ** ^Every new [database connection] defaults to having the auto-checkpoint |
| 10144 | 10225 | ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] |
| 10145 | -** pages. The use of this interface | |
| 10146 | -** is only necessary if the default setting is found to be suboptimal | |
| 10147 | -** for a particular application. | |
| 10226 | +** pages. | |
| 10227 | +** | |
| 10228 | +** ^The use of this interface is only necessary if the default setting | |
| 10229 | +** is found to be suboptimal for a particular application. | |
| 10148 | 10230 | */ |
| 10149 | 10231 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 10150 | 10232 | |
| 10151 | 10233 | /* |
| 10152 | 10234 | ** CAPI3REF: Checkpoint a database |
| @@ -10207,10 +10289,15 @@ | ||
| 10207 | 10289 | ** |
| 10208 | 10290 | ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd> |
| 10209 | 10291 | ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the |
| 10210 | 10292 | ** addition that it also truncates the log file to zero bytes just prior |
| 10211 | 10293 | ** to a successful return. |
| 10294 | +** | |
| 10295 | +** <dt>SQLITE_CHECKPOINT_NOOP<dd> | |
| 10296 | +** ^This mode always checkpoints zero frames. The only reason to invoke | |
| 10297 | +** a NOOP checkpoint is to access the values returned by | |
| 10298 | +** sqlite3_wal_checkpoint_v2() via output parameters *pnLog and *pnCkpt. | |
| 10212 | 10299 | ** </dl> |
| 10213 | 10300 | ** |
| 10214 | 10301 | ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in |
| 10215 | 10302 | ** the log file or to -1 if the checkpoint could not run because |
| 10216 | 10303 | ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not |
| @@ -10277,10 +10364,11 @@ | ||
| 10277 | 10364 | ** These constants define all valid values for the "checkpoint mode" passed |
| 10278 | 10365 | ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. |
| 10279 | 10366 | ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the |
| 10280 | 10367 | ** meaning of each of these checkpoint modes. |
| 10281 | 10368 | */ |
| 10369 | +#define SQLITE_CHECKPOINT_NOOP -1 /* Do no work at all */ | |
| 10282 | 10370 | #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ |
| 10283 | 10371 | #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ |
| 10284 | 10372 | #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ |
| 10285 | 10373 | #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ |
| 10286 | 10374 | |
| @@ -11104,11 +11192,11 @@ | ||
| 11104 | 11192 | ** to avoid a memory leak. |
| 11105 | 11193 | ** |
| 11106 | 11194 | ** The [sqlite3_snapshot_get()] interface is only available when the |
| 11107 | 11195 | ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. |
| 11108 | 11196 | */ |
| 11109 | -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( | |
| 11197 | +SQLITE_API int sqlite3_snapshot_get( | |
| 11110 | 11198 | sqlite3 *db, |
| 11111 | 11199 | const char *zSchema, |
| 11112 | 11200 | sqlite3_snapshot **ppSnapshot |
| 11113 | 11201 | ); |
| 11114 | 11202 | |
| @@ -11153,11 +11241,11 @@ | ||
| 11153 | 11241 | ** database connection in order to make it ready to use snapshots.) |
| 11154 | 11242 | ** |
| 11155 | 11243 | ** The [sqlite3_snapshot_open()] interface is only available when the |
| 11156 | 11244 | ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. |
| 11157 | 11245 | */ |
| 11158 | -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( | |
| 11246 | +SQLITE_API int sqlite3_snapshot_open( | |
| 11159 | 11247 | sqlite3 *db, |
| 11160 | 11248 | const char *zSchema, |
| 11161 | 11249 | sqlite3_snapshot *pSnapshot |
| 11162 | 11250 | ); |
| 11163 | 11251 | |
| @@ -11170,11 +11258,11 @@ | ||
| 11170 | 11258 | ** using this routine to avoid a memory leak. |
| 11171 | 11259 | ** |
| 11172 | 11260 | ** The [sqlite3_snapshot_free()] interface is only available when the |
| 11173 | 11261 | ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. |
| 11174 | 11262 | */ |
| 11175 | -SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); | |
| 11263 | +SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot*); | |
| 11176 | 11264 | |
| 11177 | 11265 | /* |
| 11178 | 11266 | ** CAPI3REF: Compare the ages of two snapshot handles. |
| 11179 | 11267 | ** METHOD: sqlite3_snapshot |
| 11180 | 11268 | ** |
| @@ -11197,11 +11285,11 @@ | ||
| 11197 | 11285 | ** snapshot, and a positive value if P1 is a newer snapshot than P2. |
| 11198 | 11286 | ** |
| 11199 | 11287 | ** This interface is only available if SQLite is compiled with the |
| 11200 | 11288 | ** [SQLITE_ENABLE_SNAPSHOT] option. |
| 11201 | 11289 | */ |
| 11202 | -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( | |
| 11290 | +SQLITE_API int sqlite3_snapshot_cmp( | |
| 11203 | 11291 | sqlite3_snapshot *p1, |
| 11204 | 11292 | sqlite3_snapshot *p2 |
| 11205 | 11293 | ); |
| 11206 | 11294 | |
| 11207 | 11295 | /* |
| @@ -11225,11 +11313,11 @@ | ||
| 11225 | 11313 | ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. |
| 11226 | 11314 | ** |
| 11227 | 11315 | ** This interface is only available if SQLite is compiled with the |
| 11228 | 11316 | ** [SQLITE_ENABLE_SNAPSHOT] option. |
| 11229 | 11317 | */ |
| 11230 | -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); | |
| 11318 | +SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); | |
| 11231 | 11319 | |
| 11232 | 11320 | /* |
| 11233 | 11321 | ** CAPI3REF: Serialize a database |
| 11234 | 11322 | ** |
| 11235 | 11323 | ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to |
| @@ -11299,16 +11387,17 @@ | ||
| 11299 | 11387 | /* |
| 11300 | 11388 | ** CAPI3REF: Deserialize a database |
| 11301 | 11389 | ** |
| 11302 | 11390 | ** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the |
| 11303 | 11391 | ** [database connection] D to disconnect from database S and then |
| 11304 | -** reopen S as an in-memory database based on the serialization contained | |
| 11305 | -** in P. The serialized database P is N bytes in size. M is the size of | |
| 11306 | -** the buffer P, which might be larger than N. If M is larger than N, and | |
| 11307 | -** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is | |
| 11308 | -** permitted to add content to the in-memory database as long as the total | |
| 11309 | -** size does not exceed M bytes. | |
| 11392 | +** reopen S as an in-memory database based on the serialization | |
| 11393 | +** contained in P. If S is a NULL pointer, the main database is | |
| 11394 | +** used. The serialized database P is N bytes in size. M is the size | |
| 11395 | +** of the buffer P, which might be larger than N. If M is larger than | |
| 11396 | +** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then | |
| 11397 | +** SQLite is permitted to add content to the in-memory database as | |
| 11398 | +** long as the total size does not exceed M bytes. | |
| 11310 | 11399 | ** |
| 11311 | 11400 | ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will |
| 11312 | 11401 | ** invoke sqlite3_free() on the serialization buffer when the database |
| 11313 | 11402 | ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then |
| 11314 | 11403 | ** SQLite will try to increase the buffer size using sqlite3_realloc64() |
| @@ -11371,10 +11460,56 @@ | ||
| 11371 | 11460 | */ |
| 11372 | 11461 | #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ |
| 11373 | 11462 | #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ |
| 11374 | 11463 | #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ |
| 11375 | 11464 | |
| 11465 | +/* | |
| 11466 | +** CAPI3REF: Bind array values to the CARRAY table-valued function | |
| 11467 | +** | |
| 11468 | +** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to | |
| 11469 | +** one of the first argument of the [carray() table-valued function]. The | |
| 11470 | +** S parameter is a pointer to the [prepared statement] that uses the carray() | |
| 11471 | +** functions. I is the parameter index to be bound. P is a pointer to the | |
| 11472 | +** array to be bound, and N is the number of eements in the array. The | |
| 11473 | +** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], | |
| 11474 | +** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to | |
| 11475 | +** indicate the datatype of the array being bound. The X argument is not a | |
| 11476 | +** NULL pointer, then SQLite will invoke the function X on the P parameter | |
| 11477 | +** after it has finished using P. | |
| 11478 | +*/ | |
| 11479 | +SQLITE_API SQLITE_API int sqlite3_carray_bind( | |
| 11480 | + sqlite3_stmt *pStmt, /* Statement to be bound */ | |
| 11481 | + int i, /* Parameter index */ | |
| 11482 | + void *aData, /* Pointer to array data */ | |
| 11483 | + int nData, /* Number of data elements */ | |
| 11484 | + int mFlags, /* CARRAY flags */ | |
| 11485 | + void (*xDel)(void*) /* Destructor for aData */ | |
| 11486 | +); | |
| 11487 | + | |
| 11488 | +/* | |
| 11489 | +** CAPI3REF: Datatypes for the CARRAY table-valued funtion | |
| 11490 | +** | |
| 11491 | +** The fifth argument to the [sqlite3_carray_bind()] interface musts be | |
| 11492 | +** one of the following constants, to specify the datatype of the array | |
| 11493 | +** that is being bound into the [carray table-valued function]. | |
| 11494 | +*/ | |
| 11495 | +#define SQLITE_CARRAY_INT32 0 /* Data is 32-bit signed integers */ | |
| 11496 | +#define SQLITE_CARRAY_INT64 1 /* Data is 64-bit signed integers */ | |
| 11497 | +#define SQLITE_CARRAY_DOUBLE 2 /* Data is doubles */ | |
| 11498 | +#define SQLITE_CARRAY_TEXT 3 /* Data is char* */ | |
| 11499 | +#define SQLITE_CARRAY_BLOB 4 /* Data is struct iovec */ | |
| 11500 | + | |
| 11501 | +/* | |
| 11502 | +** Versions of the above #defines that omit the initial SQLITE_, for | |
| 11503 | +** legacy compatibility. | |
| 11504 | +*/ | |
| 11505 | +#define CARRAY_INT32 0 /* Data is 32-bit signed integers */ | |
| 11506 | +#define CARRAY_INT64 1 /* Data is 64-bit signed integers */ | |
| 11507 | +#define CARRAY_DOUBLE 2 /* Data is doubles */ | |
| 11508 | +#define CARRAY_TEXT 3 /* Data is char* */ | |
| 11509 | +#define CARRAY_BLOB 4 /* Data is struct iovec */ | |
| 11510 | + | |
| 11376 | 11511 | /* |
| 11377 | 11512 | ** Undo the hack that converts floating point types to integer for |
| 11378 | 11513 | ** builds on processors without floating point support. |
| 11379 | 11514 | */ |
| 11380 | 11515 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| @@ -12629,10 +12764,19 @@ | ||
| 12629 | 12764 | ** CAPI3REF: Apply A Changeset To A Database |
| 12630 | 12765 | ** |
| 12631 | 12766 | ** Apply a changeset or patchset to a database. These functions attempt to |
| 12632 | 12767 | ** update the "main" database attached to handle db with the changes found in |
| 12633 | 12768 | ** the changeset passed via the second and third arguments. |
| 12769 | +** | |
| 12770 | +** All changes made by these functions are enclosed in a savepoint transaction. | |
| 12771 | +** If any other error (aside from a constraint failure when attempting to | |
| 12772 | +** write to the target database) occurs, then the savepoint transaction is | |
| 12773 | +** rolled back, restoring the target database to its original state, and an | |
| 12774 | +** SQLite error code returned. Additionally, starting with version 3.51.0, | |
| 12775 | +** an error code and error message that may be accessed using the | |
| 12776 | +** [sqlite3_errcode()] and [sqlite3_errmsg()] APIs are left in the database | |
| 12777 | +** handle. | |
| 12634 | 12778 | ** |
| 12635 | 12779 | ** The fourth argument (xFilter) passed to these functions is the "filter |
| 12636 | 12780 | ** callback". This may be passed NULL, in which case all changes in the |
| 12637 | 12781 | ** changeset are applied to the database. For sqlite3changeset_apply() and |
| 12638 | 12782 | ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once |
| @@ -12767,16 +12911,10 @@ | ||
| 12767 | 12911 | ** It is safe to execute SQL statements, including those that write to the |
| 12768 | 12912 | ** table that the callback related to, from within the xConflict callback. |
| 12769 | 12913 | ** This can be used to further customize the application's conflict |
| 12770 | 12914 | ** resolution strategy. |
| 12771 | 12915 | ** |
| 12772 | -** All changes made by these functions are enclosed in a savepoint transaction. | |
| 12773 | -** If any other error (aside from a constraint failure when attempting to | |
| 12774 | -** write to the target database) occurs, then the savepoint transaction is | |
| 12775 | -** rolled back, restoring the target database to its original state, and an | |
| 12776 | -** SQLite error code returned. | |
| 12777 | -** | |
| 12778 | 12916 | ** If the output parameters (ppRebase) and (pnRebase) are non-NULL and |
| 12779 | 12917 | ** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() |
| 12780 | 12918 | ** may set (*ppRebase) to point to a "rebase" that may be used with the |
| 12781 | 12919 | ** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) |
| 12782 | 12920 | ** is set to the size of the buffer in bytes. It is the responsibility of the |
| @@ -14351,11 +14489,11 @@ | ||
| 14351 | 14489 | |
| 14352 | 14490 | /* |
| 14353 | 14491 | ** Maximum number of pages in one database file. |
| 14354 | 14492 | ** |
| 14355 | 14493 | ** This is really just the default value for the max_page_count pragma. |
| 14356 | -** This value can be lowered (or raised) at run-time using that the | |
| 14494 | +** This value can be lowered (or raised) at run-time using the | |
| 14357 | 14495 | ** max_page_count macro. |
| 14358 | 14496 | */ |
| 14359 | 14497 | #ifndef SQLITE_MAX_PAGE_COUNT |
| 14360 | 14498 | # define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */ |
| 14361 | 14499 | #endif |
| @@ -15947,12 +16085,12 @@ | ||
| 15947 | 16085 | ** |
| 15948 | 16086 | ** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application |
| 15949 | 16087 | ** must provide its own VFS implementation together with sqlite3_os_init() |
| 15950 | 16088 | ** and sqlite3_os_end() routines. |
| 15951 | 16089 | */ |
| 15952 | -#if !defined(SQLITE_OS_KV) && !defined(SQLITE_OS_OTHER) && \ | |
| 15953 | - !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_WIN) | |
| 16090 | +#if SQLITE_OS_KV+1<=1 && SQLITE_OS_OTHER+1<=1 && \ | |
| 16091 | + SQLITE_OS_WIN+1<=1 && SQLITE_OS_UNIX+1<=1 | |
| 15954 | 16092 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ |
| 15955 | 16093 | defined(__MINGW32__) || defined(__BORLANDC__) |
| 15956 | 16094 | # define SQLITE_OS_WIN 1 |
| 15957 | 16095 | # define SQLITE_OS_UNIX 0 |
| 15958 | 16096 | # else |
| @@ -17450,10 +17588,13 @@ | ||
| 17450 | 17588 | #ifndef SQLITE_OMIT_TRACE |
| 17451 | 17589 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17452 | 17590 | #endif |
| 17453 | 17591 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17454 | 17592 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17593 | +#ifdef SQLITE_ENABLE_PERCENTILE | |
| 17594 | +SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context*); | |
| 17595 | +#endif | |
| 17455 | 17596 | |
| 17456 | 17597 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); |
| 17457 | 17598 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17458 | 17599 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17459 | 17600 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| @@ -18122,11 +18263,11 @@ | ||
| 18122 | 18263 | struct sqlite3InitInfo { /* Information used during initialization */ |
| 18123 | 18264 | Pgno newTnum; /* Rootpage of table being initialized */ |
| 18124 | 18265 | u8 iDb; /* Which db file is being initialized */ |
| 18125 | 18266 | u8 busy; /* TRUE if currently initializing */ |
| 18126 | 18267 | unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ |
| 18127 | - unsigned imposterTable : 1; /* Building an imposter table */ | |
| 18268 | + unsigned imposterTable : 2; /* Building an imposter table */ | |
| 18128 | 18269 | unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ |
| 18129 | 18270 | const char **azInit; /* "type", "name", and "tbl_name" columns */ |
| 18130 | 18271 | } init; |
| 18131 | 18272 | int nVdbeActive; /* Number of VDBEs currently running */ |
| 18132 | 18273 | int nVdbeRead; /* Number of active VDBEs that read or write */ |
| @@ -18205,10 +18346,11 @@ | ||
| 18205 | 18346 | int nStatement; /* Number of nested statement-transactions */ |
| 18206 | 18347 | i64 nDeferredCons; /* Net deferred constraints this transaction. */ |
| 18207 | 18348 | i64 nDeferredImmCons; /* Net deferred immediate constraints */ |
| 18208 | 18349 | int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ |
| 18209 | 18350 | DbClientData *pDbData; /* sqlite3_set_clientdata() content */ |
| 18351 | + u64 nSpill; /* TEMP content spilled to disk */ | |
| 18210 | 18352 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 18211 | 18353 | /* The following variables are all protected by the STATIC_MAIN |
| 18212 | 18354 | ** mutex, not by sqlite3.mutex. They are used by code in notify.c. |
| 18213 | 18355 | ** |
| 18214 | 18356 | ** When X.pUnlockConnection==Y, that means that X is waiting for Y to |
| @@ -18915,10 +19057,11 @@ | ||
| 18915 | 19057 | #define TF_Shadow 0x00001000 /* True for a shadow table */ |
| 18916 | 19058 | #define TF_HasStat4 0x00002000 /* STAT4 info available for this table */ |
| 18917 | 19059 | #define TF_Ephemeral 0x00004000 /* An ephemeral table */ |
| 18918 | 19060 | #define TF_Eponymous 0x00008000 /* An eponymous virtual table */ |
| 18919 | 19061 | #define TF_Strict 0x00010000 /* STRICT mode */ |
| 19062 | +#define TF_Imposter 0x00020000 /* An imposter table */ | |
| 18920 | 19063 | |
| 18921 | 19064 | /* |
| 18922 | 19065 | ** Allowed values for Table.eTabType |
| 18923 | 19066 | */ |
| 18924 | 19067 | #define TABTYP_NORM 0 /* Ordinary table */ |
| @@ -19503,10 +19646,11 @@ | ||
| 19503 | 19646 | AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ |
| 19504 | 19647 | union { |
| 19505 | 19648 | Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL |
| 19506 | 19649 | ** for a column of an index on an expression */ |
| 19507 | 19650 | Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */ |
| 19651 | + int nReg; /* TK_NULLS: Number of registers to NULL out */ | |
| 19508 | 19652 | struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ |
| 19509 | 19653 | int iAddr; /* Subroutine entry address */ |
| 19510 | 19654 | int regReturn; /* Register used to hold return address */ |
| 19511 | 19655 | } sub; |
| 19512 | 19656 | } y; |
| @@ -20080,10 +20224,11 @@ | ||
| 20080 | 20224 | #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ |
| 20081 | 20225 | #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ |
| 20082 | 20226 | #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ |
| 20083 | 20227 | #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ |
| 20084 | 20228 | #define SF_Correlated 0x20000000 /* True if references the outer context */ |
| 20229 | +#define SF_OnToWhere 0x40000000 /* One or more ON clauses moved to WHERE */ | |
| 20085 | 20230 | |
| 20086 | 20231 | /* True if SrcItem X is a subquery that has SF_NestedFrom */ |
| 20087 | 20232 | #define IsNestedFrom(X) \ |
| 20088 | 20233 | ((X)->fg.isSubquery && \ |
| 20089 | 20234 | ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) |
| @@ -20833,10 +20978,11 @@ | ||
| 20833 | 20978 | struct Table *pTab; /* Table of generated column */ |
| 20834 | 20979 | struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ |
| 20835 | 20980 | SrcItem *pSrcItem; /* A single FROM clause item */ |
| 20836 | 20981 | DbFixer *pFix; /* See sqlite3FixSelect() */ |
| 20837 | 20982 | Mem *aMem; /* See sqlite3BtreeCursorHint() */ |
| 20983 | + struct CheckOnCtx *pCheckOnCtx; /* See selectCheckOnClauses() */ | |
| 20838 | 20984 | } u; |
| 20839 | 20985 | }; |
| 20840 | 20986 | |
| 20841 | 20987 | /* |
| 20842 | 20988 | ** The following structure contains information used by the sqliteFix... |
| @@ -21540,10 +21686,11 @@ | ||
| 21540 | 21686 | SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); |
| 21541 | 21687 | #endif |
| 21542 | 21688 | SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); |
| 21543 | 21689 | SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); |
| 21544 | 21690 | SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); |
| 21691 | +SQLITE_PRIVATE void sqlite3ExprNullRegisterRange(Parse*, int, int); | |
| 21545 | 21692 | SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); |
| 21546 | 21693 | SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); |
| 21547 | 21694 | SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); |
| 21548 | 21695 | #define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ |
| 21549 | 21696 | #define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ |
| @@ -21636,16 +21783,20 @@ | ||
| 21636 | 21783 | SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); |
| 21637 | 21784 | SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); |
| 21638 | 21785 | SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); |
| 21639 | 21786 | SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); |
| 21640 | 21787 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) |
| 21641 | -SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3*); | |
| 21788 | +SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3*,const char*); | |
| 21642 | 21789 | #endif |
| 21643 | 21790 | SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); |
| 21644 | 21791 | SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); |
| 21645 | 21792 | SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); |
| 21646 | 21793 | SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p); |
| 21794 | + | |
| 21795 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) | |
| 21796 | +SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3*); | |
| 21797 | +#endif | |
| 21647 | 21798 | |
| 21648 | 21799 | #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) |
| 21649 | 21800 | SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); |
| 21650 | 21801 | #endif |
| 21651 | 21802 | |
| @@ -22628,10 +22779,13 @@ | ||
| 22628 | 22779 | #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE |
| 22629 | 22780 | "ENABLE_BATCH_ATOMIC_WRITE", |
| 22630 | 22781 | #endif |
| 22631 | 22782 | #ifdef SQLITE_ENABLE_BYTECODE_VTAB |
| 22632 | 22783 | "ENABLE_BYTECODE_VTAB", |
| 22784 | +#endif | |
| 22785 | +#ifdef SQLITE_ENABLE_CARRAY | |
| 22786 | + "ENABLE_CARRAY", | |
| 22633 | 22787 | #endif |
| 22634 | 22788 | #ifdef SQLITE_ENABLE_CEROD |
| 22635 | 22789 | "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), |
| 22636 | 22790 | #endif |
| 22637 | 22791 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
| @@ -22718,10 +22872,13 @@ | ||
| 22718 | 22872 | #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES |
| 22719 | 22873 | "ENABLE_ORDERED_SET_AGGREGATES", |
| 22720 | 22874 | #endif |
| 22721 | 22875 | #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK |
| 22722 | 22876 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 22877 | +#endif | |
| 22878 | +#ifdef SQLITE_ENABLE_PERCENTILE | |
| 22879 | + "ENABLE_PERCENTILE", | |
| 22723 | 22880 | #endif |
| 22724 | 22881 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 22725 | 22882 | "ENABLE_PREUPDATE_HOOK", |
| 22726 | 22883 | #endif |
| 22727 | 22884 | #ifdef SQLITE_ENABLE_QPSG |
| @@ -24202,11 +24359,14 @@ | ||
| 24202 | 24359 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24203 | 24360 | Mem *aNew; /* Array of new.* values */ |
| 24204 | 24361 | Table *pTab; /* Schema object being updated */ |
| 24205 | 24362 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24206 | 24363 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24207 | - u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ | |
| 24364 | + union { | |
| 24365 | + KeyInfo sKey; | |
| 24366 | + u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ | |
| 24367 | + } uKey; | |
| 24208 | 24368 | }; |
| 24209 | 24369 | |
| 24210 | 24370 | /* |
| 24211 | 24371 | ** An instance of this object is used to pass an vector of values into |
| 24212 | 24372 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -24366,13 +24526,15 @@ | ||
| 24366 | 24526 | SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); |
| 24367 | 24527 | SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*); |
| 24368 | 24528 | #endif |
| 24369 | 24529 | |
| 24370 | 24530 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 24371 | -SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); | |
| 24531 | +SQLITE_PRIVATE int sqlite3VdbeCheckFkImmediate(Vdbe*); | |
| 24532 | +SQLITE_PRIVATE int sqlite3VdbeCheckFkDeferred(Vdbe*); | |
| 24372 | 24533 | #else |
| 24373 | -# define sqlite3VdbeCheckFk(p,i) 0 | |
| 24534 | +# define sqlite3VdbeCheckFkImmediate(p) 0 | |
| 24535 | +# define sqlite3VdbeCheckFkDeferred(p) 0 | |
| 24374 | 24536 | #endif |
| 24375 | 24537 | |
| 24376 | 24538 | #ifdef SQLITE_DEBUG |
| 24377 | 24539 | SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); |
| 24378 | 24540 | SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr); |
| @@ -24577,27 +24739,29 @@ | ||
| 24577 | 24739 | } |
| 24578 | 24740 | |
| 24579 | 24741 | /* |
| 24580 | 24742 | ** Query status information for a single database connection |
| 24581 | 24743 | */ |
| 24582 | -SQLITE_API int sqlite3_db_status( | |
| 24583 | - sqlite3 *db, /* The database connection whose status is desired */ | |
| 24584 | - int op, /* Status verb */ | |
| 24585 | - int *pCurrent, /* Write current value here */ | |
| 24586 | - int *pHighwater, /* Write high-water mark here */ | |
| 24587 | - int resetFlag /* Reset high-water mark if true */ | |
| 24744 | +SQLITE_API int sqlite3_db_status64( | |
| 24745 | + sqlite3 *db, /* The database connection whose status is desired */ | |
| 24746 | + int op, /* Status verb */ | |
| 24747 | + sqlite3_int64 *pCurrent, /* Write current value here */ | |
| 24748 | + sqlite3_int64 *pHighwtr, /* Write high-water mark here */ | |
| 24749 | + int resetFlag /* Reset high-water mark if true */ | |
| 24588 | 24750 | ){ |
| 24589 | 24751 | int rc = SQLITE_OK; /* Return code */ |
| 24590 | 24752 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 24591 | - if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ | |
| 24753 | + if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){ | |
| 24592 | 24754 | return SQLITE_MISUSE_BKPT; |
| 24593 | 24755 | } |
| 24594 | 24756 | #endif |
| 24595 | 24757 | sqlite3_mutex_enter(db->mutex); |
| 24596 | 24758 | switch( op ){ |
| 24597 | 24759 | case SQLITE_DBSTATUS_LOOKASIDE_USED: { |
| 24598 | - *pCurrent = sqlite3LookasideUsed(db, pHighwater); | |
| 24760 | + int H = 0; | |
| 24761 | + *pCurrent = sqlite3LookasideUsed(db, &H); | |
| 24762 | + *pHighwtr = H; | |
| 24599 | 24763 | if( resetFlag ){ |
| 24600 | 24764 | LookasideSlot *p = db->lookaside.pFree; |
| 24601 | 24765 | if( p ){ |
| 24602 | 24766 | while( p->pNext ) p = p->pNext; |
| 24603 | 24767 | p->pNext = db->lookaside.pInit; |
| @@ -24624,11 +24788,11 @@ | ||
| 24624 | 24788 | testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); |
| 24625 | 24789 | testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); |
| 24626 | 24790 | assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); |
| 24627 | 24791 | assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); |
| 24628 | 24792 | *pCurrent = 0; |
| 24629 | - *pHighwater = (int)db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; | |
| 24793 | + *pHighwtr = db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; | |
| 24630 | 24794 | if( resetFlag ){ |
| 24631 | 24795 | db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; |
| 24632 | 24796 | } |
| 24633 | 24797 | break; |
| 24634 | 24798 | } |
| @@ -24638,11 +24802,11 @@ | ||
| 24638 | 24802 | ** by all pagers associated with the given database connection. The |
| 24639 | 24803 | ** highwater mark is meaningless and is returned as zero. |
| 24640 | 24804 | */ |
| 24641 | 24805 | case SQLITE_DBSTATUS_CACHE_USED_SHARED: |
| 24642 | 24806 | case SQLITE_DBSTATUS_CACHE_USED: { |
| 24643 | - int totalUsed = 0; | |
| 24807 | + sqlite3_int64 totalUsed = 0; | |
| 24644 | 24808 | int i; |
| 24645 | 24809 | sqlite3BtreeEnterAll(db); |
| 24646 | 24810 | for(i=0; i<db->nDb; i++){ |
| 24647 | 24811 | Btree *pBt = db->aDb[i].pBt; |
| 24648 | 24812 | if( pBt ){ |
| @@ -24654,22 +24818,22 @@ | ||
| 24654 | 24818 | totalUsed += nByte; |
| 24655 | 24819 | } |
| 24656 | 24820 | } |
| 24657 | 24821 | sqlite3BtreeLeaveAll(db); |
| 24658 | 24822 | *pCurrent = totalUsed; |
| 24659 | - *pHighwater = 0; | |
| 24823 | + *pHighwtr = 0; | |
| 24660 | 24824 | break; |
| 24661 | 24825 | } |
| 24662 | 24826 | |
| 24663 | 24827 | /* |
| 24664 | 24828 | ** *pCurrent gets an accurate estimate of the amount of memory used |
| 24665 | 24829 | ** to store the schema for all databases (main, temp, and any ATTACHed |
| 24666 | - ** databases. *pHighwater is set to zero. | |
| 24830 | + ** databases. *pHighwtr is set to zero. | |
| 24667 | 24831 | */ |
| 24668 | 24832 | case SQLITE_DBSTATUS_SCHEMA_USED: { |
| 24669 | - int i; /* Used to iterate through schemas */ | |
| 24670 | - int nByte = 0; /* Used to accumulate return value */ | |
| 24833 | + int i; /* Used to iterate through schemas */ | |
| 24834 | + int nByte = 0; /* Used to accumulate return value */ | |
| 24671 | 24835 | |
| 24672 | 24836 | sqlite3BtreeEnterAll(db); |
| 24673 | 24837 | db->pnBytesFreed = &nByte; |
| 24674 | 24838 | assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); |
| 24675 | 24839 | db->lookaside.pEnd = db->lookaside.pStart; |
| @@ -24699,19 +24863,19 @@ | ||
| 24699 | 24863 | } |
| 24700 | 24864 | db->pnBytesFreed = 0; |
| 24701 | 24865 | db->lookaside.pEnd = db->lookaside.pTrueEnd; |
| 24702 | 24866 | sqlite3BtreeLeaveAll(db); |
| 24703 | 24867 | |
| 24704 | - *pHighwater = 0; | |
| 24868 | + *pHighwtr = 0; | |
| 24705 | 24869 | *pCurrent = nByte; |
| 24706 | 24870 | break; |
| 24707 | 24871 | } |
| 24708 | 24872 | |
| 24709 | 24873 | /* |
| 24710 | 24874 | ** *pCurrent gets an accurate estimate of the amount of memory used |
| 24711 | 24875 | ** to store all prepared statements. |
| 24712 | - ** *pHighwater is set to zero. | |
| 24876 | + ** *pHighwtr is set to zero. | |
| 24713 | 24877 | */ |
| 24714 | 24878 | case SQLITE_DBSTATUS_STMT_USED: { |
| 24715 | 24879 | struct Vdbe *pVdbe; /* Used to iterate through VMs */ |
| 24716 | 24880 | int nByte = 0; /* Used to accumulate return value */ |
| 24717 | 24881 | |
| @@ -24722,19 +24886,19 @@ | ||
| 24722 | 24886 | sqlite3VdbeDelete(pVdbe); |
| 24723 | 24887 | } |
| 24724 | 24888 | db->lookaside.pEnd = db->lookaside.pTrueEnd; |
| 24725 | 24889 | db->pnBytesFreed = 0; |
| 24726 | 24890 | |
| 24727 | - *pHighwater = 0; /* IMP: R-64479-57858 */ | |
| 24891 | + *pHighwtr = 0; /* IMP: R-64479-57858 */ | |
| 24728 | 24892 | *pCurrent = nByte; |
| 24729 | 24893 | |
| 24730 | 24894 | break; |
| 24731 | 24895 | } |
| 24732 | 24896 | |
| 24733 | 24897 | /* |
| 24734 | 24898 | ** Set *pCurrent to the total cache hits or misses encountered by all |
| 24735 | - ** pagers the database handle is connected to. *pHighwater is always set | |
| 24899 | + ** pagers the database handle is connected to. *pHighwtr is always set | |
| 24736 | 24900 | ** to zero. |
| 24737 | 24901 | */ |
| 24738 | 24902 | case SQLITE_DBSTATUS_CACHE_SPILL: |
| 24739 | 24903 | op = SQLITE_DBSTATUS_CACHE_WRITE+1; |
| 24740 | 24904 | /* no break */ deliberate_fall_through |
| @@ -24750,23 +24914,43 @@ | ||
| 24750 | 24914 | if( db->aDb[i].pBt ){ |
| 24751 | 24915 | Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); |
| 24752 | 24916 | sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); |
| 24753 | 24917 | } |
| 24754 | 24918 | } |
| 24755 | - *pHighwater = 0; /* IMP: R-42420-56072 */ | |
| 24919 | + *pHighwtr = 0; /* IMP: R-42420-56072 */ | |
| 24756 | 24920 | /* IMP: R-54100-20147 */ |
| 24757 | 24921 | /* IMP: R-29431-39229 */ |
| 24758 | - *pCurrent = (int)nRet & 0x7fffffff; | |
| 24922 | + *pCurrent = nRet; | |
| 24923 | + break; | |
| 24924 | + } | |
| 24925 | + | |
| 24926 | + /* Set *pCurrent to the number of bytes that the db database connection | |
| 24927 | + ** has spilled to the filesystem in temporary files that could have been | |
| 24928 | + ** stored in memory, had sufficient memory been available. | |
| 24929 | + ** The *pHighwater is always set to zero. | |
| 24930 | + */ | |
| 24931 | + case SQLITE_DBSTATUS_TEMPBUF_SPILL: { | |
| 24932 | + u64 nRet = 0; | |
| 24933 | + if( db->aDb[1].pBt ){ | |
| 24934 | + Pager *pPager = sqlite3BtreePager(db->aDb[1].pBt); | |
| 24935 | + sqlite3PagerCacheStat(pPager, SQLITE_DBSTATUS_CACHE_WRITE, | |
| 24936 | + resetFlag, &nRet); | |
| 24937 | + nRet *= sqlite3BtreeGetPageSize(db->aDb[1].pBt); | |
| 24938 | + } | |
| 24939 | + nRet += db->nSpill; | |
| 24940 | + if( resetFlag ) db->nSpill = 0; | |
| 24941 | + *pHighwtr = 0; | |
| 24942 | + *pCurrent = nRet; | |
| 24759 | 24943 | break; |
| 24760 | 24944 | } |
| 24761 | 24945 | |
| 24762 | 24946 | /* Set *pCurrent to non-zero if there are unresolved deferred foreign |
| 24763 | 24947 | ** key constraints. Set *pCurrent to zero if all foreign key constraints |
| 24764 | - ** have been satisfied. The *pHighwater is always set to zero. | |
| 24948 | + ** have been satisfied. The *pHighwtr is always set to zero. | |
| 24765 | 24949 | */ |
| 24766 | 24950 | case SQLITE_DBSTATUS_DEFERRED_FKS: { |
| 24767 | - *pHighwater = 0; /* IMP: R-11967-56545 */ | |
| 24951 | + *pHighwtr = 0; /* IMP: R-11967-56545 */ | |
| 24768 | 24952 | *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0; |
| 24769 | 24953 | break; |
| 24770 | 24954 | } |
| 24771 | 24955 | |
| 24772 | 24956 | default: { |
| @@ -24774,10 +24958,35 @@ | ||
| 24774 | 24958 | } |
| 24775 | 24959 | } |
| 24776 | 24960 | sqlite3_mutex_leave(db->mutex); |
| 24777 | 24961 | return rc; |
| 24778 | 24962 | } |
| 24963 | + | |
| 24964 | +/* | |
| 24965 | +** 32-bit variant of sqlite3_db_status64() | |
| 24966 | +*/ | |
| 24967 | +SQLITE_API int sqlite3_db_status( | |
| 24968 | + sqlite3 *db, /* The database connection whose status is desired */ | |
| 24969 | + int op, /* Status verb */ | |
| 24970 | + int *pCurrent, /* Write current value here */ | |
| 24971 | + int *pHighwtr, /* Write high-water mark here */ | |
| 24972 | + int resetFlag /* Reset high-water mark if true */ | |
| 24973 | +){ | |
| 24974 | + sqlite3_int64 C = 0, H = 0; | |
| 24975 | + int rc; | |
| 24976 | +#ifdef SQLITE_ENABLE_API_ARMOR | |
| 24977 | + if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){ | |
| 24978 | + return SQLITE_MISUSE_BKPT; | |
| 24979 | + } | |
| 24980 | +#endif | |
| 24981 | + rc = sqlite3_db_status64(db, op, &C, &H, resetFlag); | |
| 24982 | + if( rc==0 ){ | |
| 24983 | + *pCurrent = C & 0x7fffffff; | |
| 24984 | + *pHighwtr = H & 0x7fffffff; | |
| 24985 | + } | |
| 24986 | + return rc; | |
| 24987 | +} | |
| 24779 | 24988 | |
| 24780 | 24989 | /************** End of status.c **********************************************/ |
| 24781 | 24990 | /************** Begin file date.c ********************************************/ |
| 24782 | 24991 | /* |
| 24783 | 24992 | ** 2003 October 31 |
| @@ -24967,10 +25176,14 @@ | ||
| 24967 | 25176 | if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){ |
| 24968 | 25177 | return 1; |
| 24969 | 25178 | } |
| 24970 | 25179 | zDate += 5; |
| 24971 | 25180 | p->tz = sgn*(nMn + nHr*60); |
| 25181 | + if( p->tz==0 ){ /* Forum post 2025-09-17T10:12:14z */ | |
| 25182 | + p->isLocal = 0; | |
| 25183 | + p->isUtc = 1; | |
| 25184 | + } | |
| 24972 | 25185 | zulu_time: |
| 24973 | 25186 | while( sqlite3Isspace(*zDate) ){ zDate++; } |
| 24974 | 25187 | return *zDate!=0; |
| 24975 | 25188 | } |
| 24976 | 25189 | |
| @@ -26162,12 +26375,12 @@ | ||
| 26162 | 26375 | ** %j day of year 001-366 |
| 26163 | 26376 | ** %J ** julian day number |
| 26164 | 26377 | ** %l hour 1-12 (leading zero converted to space) |
| 26165 | 26378 | ** %m month 01-12 |
| 26166 | 26379 | ** %M minute 00-59 |
| 26167 | -** %p "am" or "pm" | |
| 26168 | -** %P "AM" or "PM" | |
| 26380 | +** %p "AM" or "PM" | |
| 26381 | +** %P "am" or "pm" | |
| 26169 | 26382 | ** %R time as HH:MM |
| 26170 | 26383 | ** %s seconds since 1970-01-01 |
| 26171 | 26384 | ** %S seconds 00-59 |
| 26172 | 26385 | ** %T time as HH:MM:SS |
| 26173 | 26386 | ** %u day of week 1-7 Monday==1, Sunday==7 |
| @@ -31770,56 +31983,74 @@ | ||
| 31770 | 31983 | etByte base; /* The base for radix conversion */ |
| 31771 | 31984 | etByte flags; /* One or more of FLAG_ constants below */ |
| 31772 | 31985 | etByte type; /* Conversion paradigm */ |
| 31773 | 31986 | etByte charset; /* Offset into aDigits[] of the digits string */ |
| 31774 | 31987 | etByte prefix; /* Offset into aPrefix[] of the prefix string */ |
| 31988 | + char iNxt; /* Next with same hash, or 0 for end of chain */ | |
| 31775 | 31989 | } et_info; |
| 31776 | 31990 | |
| 31777 | 31991 | /* |
| 31778 | 31992 | ** Allowed values for et_info.flags |
| 31779 | 31993 | */ |
| 31780 | 31994 | #define FLAG_SIGNED 1 /* True if the value to convert is signed */ |
| 31781 | 31995 | #define FLAG_STRING 4 /* Allow infinite precision */ |
| 31782 | 31996 | |
| 31997 | +/* | |
| 31998 | +** The table is searched by hash. In the case of %C where C is the character | |
| 31999 | +** and that character has ASCII value j, then the hash is j%23. | |
| 32000 | +** | |
| 32001 | +** The order of the entries in fmtinfo[] and the hash chain was entered | |
| 32002 | +** manually, but based on the output of the following TCL script: | |
| 32003 | +*/ | |
| 32004 | +#if 0 /***** Beginning of script ******/ | |
| 32005 | +foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} { | |
| 32006 | + scan $c %c x | |
| 32007 | + set n($c) $x | |
| 32008 | +} | |
| 32009 | +set mx [llength [array names n]] | |
| 32010 | +puts "count: $mx" | |
| 31783 | 32011 | |
| 31784 | -/* | |
| 31785 | -** The following table is searched linearly, so it is good to put the | |
| 31786 | -** most frequently used conversion types first. | |
| 31787 | -*/ | |
| 32012 | +set mx 27 | |
| 32013 | +puts "*********** mx=$mx ************" | |
| 32014 | +for {set r 0} {$r<$mx} {incr r} { | |
| 32015 | + puts -nonewline [format %2d: $r] | |
| 32016 | + foreach c [array names n] { | |
| 32017 | + if {($n($c))%$mx==$r} {puts -nonewline " $c"} | |
| 32018 | + } | |
| 32019 | + puts "" | |
| 32020 | +} | |
| 32021 | +#endif /***** End of script ********/ | |
| 32022 | + | |
| 31788 | 32023 | static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; |
| 31789 | 32024 | static const char aPrefix[] = "-x0\000X0"; |
| 31790 | -static const et_info fmtinfo[] = { | |
| 31791 | - { 'd', 10, 1, etDECIMAL, 0, 0 }, | |
| 31792 | - { 's', 0, 4, etSTRING, 0, 0 }, | |
| 31793 | - { 'g', 0, 1, etGENERIC, 30, 0 }, | |
| 31794 | - { 'z', 0, 4, etDYNSTRING, 0, 0 }, | |
| 31795 | - { 'q', 0, 4, etESCAPE_q, 0, 0 }, | |
| 31796 | - { 'Q', 0, 4, etESCAPE_Q, 0, 0 }, | |
| 31797 | - { 'w', 0, 4, etESCAPE_w, 0, 0 }, | |
| 31798 | - { 'c', 0, 0, etCHARX, 0, 0 }, | |
| 31799 | - { 'o', 8, 0, etRADIX, 0, 2 }, | |
| 31800 | - { 'u', 10, 0, etDECIMAL, 0, 0 }, | |
| 31801 | - { 'x', 16, 0, etRADIX, 16, 1 }, | |
| 31802 | - { 'X', 16, 0, etRADIX, 0, 4 }, | |
| 31803 | -#ifndef SQLITE_OMIT_FLOATING_POINT | |
| 31804 | - { 'f', 0, 1, etFLOAT, 0, 0 }, | |
| 31805 | - { 'e', 0, 1, etEXP, 30, 0 }, | |
| 31806 | - { 'E', 0, 1, etEXP, 14, 0 }, | |
| 31807 | - { 'G', 0, 1, etGENERIC, 14, 0 }, | |
| 31808 | -#endif | |
| 31809 | - { 'i', 10, 1, etDECIMAL, 0, 0 }, | |
| 31810 | - { 'n', 0, 0, etSIZE, 0, 0 }, | |
| 31811 | - { '%', 0, 0, etPERCENT, 0, 0 }, | |
| 31812 | - { 'p', 16, 0, etPOINTER, 0, 1 }, | |
| 31813 | - | |
| 31814 | - /* All the rest are undocumented and are for internal use only */ | |
| 31815 | - { 'T', 0, 0, etTOKEN, 0, 0 }, | |
| 31816 | - { 'S', 0, 0, etSRCITEM, 0, 0 }, | |
| 31817 | - { 'r', 10, 1, etORDINAL, 0, 0 }, | |
| 32025 | +static const et_info fmtinfo[23] = { | |
| 32026 | + /* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 }, | |
| 32027 | + /* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */ | |
| 32028 | + /* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 }, | |
| 32029 | + /* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */ | |
| 32030 | + /* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, | |
| 32031 | + /* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, | |
| 32032 | + /* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */ | |
| 32033 | + /* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 }, | |
| 32034 | + /* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, | |
| 32035 | + /* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, | |
| 32036 | + /* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, | |
| 32037 | + /* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, | |
| 32038 | + /* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 }, | |
| 32039 | + /* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, | |
| 32040 | + /* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 }, | |
| 32041 | + /* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, | |
| 32042 | + /* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */ | |
| 32043 | + /* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */ | |
| 32044 | + /* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, | |
| 32045 | + /* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 }, | |
| 32046 | + /* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, | |
| 32047 | + /* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 }, | |
| 32048 | + /* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 } | |
| 31818 | 32049 | }; |
| 31819 | 32050 | |
| 31820 | -/* Notes: | |
| 32051 | +/* Additional Notes: | |
| 31821 | 32052 | ** |
| 31822 | 32053 | ** %S Takes a pointer to SrcItem. Shows name or database.name |
| 31823 | 32054 | ** %!S Like %S but prefer the zName over the zAlias |
| 31824 | 32055 | */ |
| 31825 | 32056 | |
| @@ -31942,11 +32173,14 @@ | ||
| 31942 | 32173 | if( c!='%' ){ |
| 31943 | 32174 | bufpt = (char *)fmt; |
| 31944 | 32175 | #if HAVE_STRCHRNUL |
| 31945 | 32176 | fmt = strchrnul(fmt, '%'); |
| 31946 | 32177 | #else |
| 31947 | - do{ fmt++; }while( *fmt && *fmt != '%' ); | |
| 32178 | + fmt = strchr(fmt, '%'); | |
| 32179 | + if( fmt==0 ){ | |
| 32180 | + fmt = bufpt + strlen(bufpt); | |
| 32181 | + } | |
| 31948 | 32182 | #endif |
| 31949 | 32183 | sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); |
| 31950 | 32184 | if( *fmt==0 ) break; |
| 31951 | 32185 | } |
| 31952 | 32186 | if( (c=(*++fmt))==0 ){ |
| @@ -32056,19 +32290,36 @@ | ||
| 32056 | 32290 | } |
| 32057 | 32291 | } |
| 32058 | 32292 | }while( !done && (c=(*++fmt))!=0 ); |
| 32059 | 32293 | |
| 32060 | 32294 | /* Fetch the info entry for the field */ |
| 32295 | +#ifdef SQLITE_EBCDIC | |
| 32296 | + /* The hash table only works for ASCII. For EBCDIC, we need to do | |
| 32297 | + ** a linear search of the table */ | |
| 32061 | 32298 | infop = &fmtinfo[0]; |
| 32062 | 32299 | xtype = etINVALID; |
| 32063 | 32300 | for(idx=0; idx<ArraySize(fmtinfo); idx++){ |
| 32064 | 32301 | if( c==fmtinfo[idx].fmttype ){ |
| 32065 | 32302 | infop = &fmtinfo[idx]; |
| 32066 | 32303 | xtype = infop->type; |
| 32067 | 32304 | break; |
| 32068 | 32305 | } |
| 32069 | 32306 | } |
| 32307 | +#else | |
| 32308 | + /* Fast hash-table lookup */ | |
| 32309 | + assert( ArraySize(fmtinfo)==23 ); | |
| 32310 | + idx = ((unsigned)c) % 23; | |
| 32311 | + if( fmtinfo[idx].fmttype==c | |
| 32312 | + || fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c | |
| 32313 | + ){ | |
| 32314 | + infop = &fmtinfo[idx]; | |
| 32315 | + xtype = infop->type; | |
| 32316 | + }else{ | |
| 32317 | + infop = &fmtinfo[0]; | |
| 32318 | + xtype = etINVALID; | |
| 32319 | + } | |
| 32320 | +#endif | |
| 32070 | 32321 | |
| 32071 | 32322 | /* |
| 32072 | 32323 | ** At this point, variables are initialized as follows: |
| 32073 | 32324 | ** |
| 32074 | 32325 | ** flag_alternateform TRUE if a '#' is present. |
| @@ -32252,11 +32503,25 @@ | ||
| 32252 | 32503 | length = sqlite3Strlen30(bufpt); |
| 32253 | 32504 | break; |
| 32254 | 32505 | } |
| 32255 | 32506 | } |
| 32256 | 32507 | if( s.sign=='-' ){ |
| 32257 | - prefix = '-'; | |
| 32508 | + if( flag_alternateform | |
| 32509 | + && !flag_prefix | |
| 32510 | + && xtype==etFLOAT | |
| 32511 | + && s.iDP<=iRound | |
| 32512 | + ){ | |
| 32513 | + /* Suppress the minus sign if all of the following are true: | |
| 32514 | + ** * The value displayed is zero | |
| 32515 | + ** * The '#' flag is used | |
| 32516 | + ** * The '+' flag is not used, and | |
| 32517 | + ** * The format is %f | |
| 32518 | + */ | |
| 32519 | + prefix = 0; | |
| 32520 | + }else{ | |
| 32521 | + prefix = '-'; | |
| 32522 | + } | |
| 32258 | 32523 | }else{ |
| 32259 | 32524 | prefix = flag_prefix; |
| 32260 | 32525 | } |
| 32261 | 32526 | |
| 32262 | 32527 | exp = s.iDP-1; |
| @@ -33463,13 +33728,17 @@ | ||
| 33463 | 33728 | sqlite3StrAccumFinish(&x); |
| 33464 | 33729 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); |
| 33465 | 33730 | n = 0; |
| 33466 | 33731 | if( pItem->fg.isSubquery ) n++; |
| 33467 | 33732 | if( pItem->fg.isTabFunc ) n++; |
| 33468 | - if( pItem->fg.isUsing ) n++; | |
| 33733 | + if( pItem->fg.isUsing || pItem->u3.pOn!=0 ) n++; | |
| 33469 | 33734 | if( pItem->fg.isUsing ){ |
| 33470 | 33735 | sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); |
| 33736 | + }else if( pItem->u3.pOn!=0 ){ | |
| 33737 | + sqlite3TreeViewItem(pView, "ON", (--n)>0); | |
| 33738 | + sqlite3TreeViewExpr(pView, pItem->u3.pOn, 0); | |
| 33739 | + sqlite3TreeViewPop(&pView); | |
| 33471 | 33740 | } |
| 33472 | 33741 | if( pItem->fg.isSubquery ){ |
| 33473 | 33742 | assert( n==1 ); |
| 33474 | 33743 | if( pItem->pSTab ){ |
| 33475 | 33744 | Table *pTab = pItem->pSTab; |
| @@ -38108,11 +38377,11 @@ | ||
| 38108 | 38377 | static int kvstorageDelete(const char*, const char *zKey); |
| 38109 | 38378 | static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf); |
| 38110 | 38379 | #define KVSTORAGE_KEY_SZ 32 |
| 38111 | 38380 | |
| 38112 | 38381 | /* Expand the key name with an appropriate prefix and put the result |
| 38113 | -** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least | |
| 38382 | +** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least | |
| 38114 | 38383 | ** KVSTORAGE_KEY_SZ bytes. |
| 38115 | 38384 | */ |
| 38116 | 38385 | static void kvstorageMakeKey( |
| 38117 | 38386 | const char *zClass, |
| 38118 | 38387 | const char *zKeyIn, |
| @@ -38167,14 +38436,16 @@ | ||
| 38167 | 38436 | ** enough to hold it all. The value put into zBuf must always be zero |
| 38168 | 38437 | ** terminated, even if it gets truncated because nBuf is not large enough. |
| 38169 | 38438 | ** |
| 38170 | 38439 | ** Return the total number of bytes in the data, without truncation, and |
| 38171 | 38440 | ** not counting the final zero terminator. Return -1 if the key does |
| 38172 | -** not exist. | |
| 38441 | +** not exist or its key cannot be read. | |
| 38173 | 38442 | ** |
| 38174 | -** If nBuf<=0 then this routine simply returns the size of the data without | |
| 38175 | -** actually reading it. | |
| 38443 | +** If nBuf<=0 then this routine simply returns the size of the data | |
| 38444 | +** without actually reading it. Similarly, if nBuf==1 then it | |
| 38445 | +** zero-terminates zBuf at zBuf[0] and returns the size of the data | |
| 38446 | +** without reading it. | |
| 38176 | 38447 | */ |
| 38177 | 38448 | static int kvstorageRead( |
| 38178 | 38449 | const char *zClass, |
| 38179 | 38450 | const char *zKey, |
| 38180 | 38451 | char *zBuf, |
| @@ -38219,15 +38490,13 @@ | ||
| 38219 | 38490 | /* |
| 38220 | 38491 | ** An internal level of indirection which enables us to replace the |
| 38221 | 38492 | ** kvvfs i/o methods with JavaScript implementations in WASM builds. |
| 38222 | 38493 | ** Maintenance reminder: if this struct changes in any way, the JSON |
| 38223 | 38494 | ** rendering of its structure must be updated in |
| 38224 | -** sqlite3_wasm_enum_json(). There are no binary compatibility | |
| 38225 | -** concerns, so it does not need an iVersion member. This file is | |
| 38226 | -** necessarily always compiled together with sqlite3_wasm_enum_json(), | |
| 38227 | -** and JS code dynamically creates the mapping of members based on | |
| 38228 | -** that JSON description. | |
| 38495 | +** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary | |
| 38496 | +** compatibility concerns, so it does not need an iVersion | |
| 38497 | +** member. | |
| 38229 | 38498 | */ |
| 38230 | 38499 | typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; |
| 38231 | 38500 | struct sqlite3_kvvfs_methods { |
| 38232 | 38501 | int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf); |
| 38233 | 38502 | int (*xWrite)(const char *zClass, const char *zKey, const char *zData); |
| @@ -38240,12 +38509,12 @@ | ||
| 38240 | 38509 | ** for JavaScript-side implementations in WASM builds. In such builds |
| 38241 | 38510 | ** it cannot be const, but in native builds it should be so that |
| 38242 | 38511 | ** the compiler can hopefully optimize this level of indirection out. |
| 38243 | 38512 | ** That said, kvvfs is intended primarily for use in WASM builds. |
| 38244 | 38513 | ** |
| 38245 | -** Note that this is not explicitly flagged as static because the | |
| 38246 | -** amalgamation build will tag it with SQLITE_PRIVATE. | |
| 38514 | +** This is not explicitly flagged as static because the amalgamation | |
| 38515 | +** build will tag it with SQLITE_PRIVATE. | |
| 38247 | 38516 | */ |
| 38248 | 38517 | #ifndef SQLITE_WASM |
| 38249 | 38518 | const |
| 38250 | 38519 | #endif |
| 38251 | 38520 | SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { |
| @@ -39414,14 +39683,15 @@ | ||
| 39414 | 39683 | #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ |
| 39415 | 39684 | aSyscall[13].pCurrent) |
| 39416 | 39685 | |
| 39417 | 39686 | #if defined(HAVE_FCHMOD) |
| 39418 | 39687 | { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, |
| 39688 | +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) | |
| 39419 | 39689 | #else |
| 39420 | 39690 | { "fchmod", (sqlite3_syscall_ptr)0, 0 }, |
| 39691 | +#define osFchmod(FID,MODE) 0 | |
| 39421 | 39692 | #endif |
| 39422 | -#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) | |
| 39423 | 39693 | |
| 39424 | 39694 | #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE |
| 39425 | 39695 | { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, |
| 39426 | 39696 | #else |
| 39427 | 39697 | { "fallocate", (sqlite3_syscall_ptr)0, 0 }, |
| @@ -39675,13 +39945,12 @@ | ||
| 39675 | 39945 | return fd; |
| 39676 | 39946 | } |
| 39677 | 39947 | |
| 39678 | 39948 | /* |
| 39679 | 39949 | ** Helper functions to obtain and relinquish the global mutex. The |
| 39680 | -** global mutex is used to protect the unixInodeInfo and | |
| 39681 | -** vxworksFileId objects used by this file, all of which may be | |
| 39682 | -** shared by multiple threads. | |
| 39950 | +** global mutex is used to protect the unixInodeInfo objects used by | |
| 39951 | +** this file, all of which may be shared by multiple threads. | |
| 39683 | 39952 | ** |
| 39684 | 39953 | ** Function unixMutexHeld() is used to assert() that the global mutex |
| 39685 | 39954 | ** is held when required. This function is only used as part of assert() |
| 39686 | 39955 | ** statements. e.g. |
| 39687 | 39956 | ** |
| @@ -39879,10 +40148,11 @@ | ||
| 39879 | 40148 | /* |
| 39880 | 40149 | ** All unique filenames are held on a linked list headed by this |
| 39881 | 40150 | ** variable: |
| 39882 | 40151 | */ |
| 39883 | 40152 | static struct vxworksFileId *vxworksFileList = 0; |
| 40153 | +static sqlite3_mutex *vxworksMutex = 0; | |
| 39884 | 40154 | |
| 39885 | 40155 | /* |
| 39886 | 40156 | ** Simplify a filename into its canonical form |
| 39887 | 40157 | ** by making the following changes: |
| 39888 | 40158 | ** |
| @@ -39944,47 +40214,47 @@ | ||
| 39944 | 40214 | |
| 39945 | 40215 | /* Search for an existing entry that matching the canonical name. |
| 39946 | 40216 | ** If found, increment the reference count and return a pointer to |
| 39947 | 40217 | ** the existing file ID. |
| 39948 | 40218 | */ |
| 39949 | - unixEnterMutex(); | |
| 40219 | + sqlite3_mutex_enter(vxworksMutex); | |
| 39950 | 40220 | for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ |
| 39951 | 40221 | if( pCandidate->nName==n |
| 39952 | 40222 | && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 |
| 39953 | 40223 | ){ |
| 39954 | 40224 | sqlite3_free(pNew); |
| 39955 | 40225 | pCandidate->nRef++; |
| 39956 | - unixLeaveMutex(); | |
| 40226 | + sqlite3_mutex_leave(vxworksMutex); | |
| 39957 | 40227 | return pCandidate; |
| 39958 | 40228 | } |
| 39959 | 40229 | } |
| 39960 | 40230 | |
| 39961 | 40231 | /* No match was found. We will make a new file ID */ |
| 39962 | 40232 | pNew->nRef = 1; |
| 39963 | 40233 | pNew->nName = n; |
| 39964 | 40234 | pNew->pNext = vxworksFileList; |
| 39965 | 40235 | vxworksFileList = pNew; |
| 39966 | - unixLeaveMutex(); | |
| 40236 | + sqlite3_mutex_leave(vxworksMutex); | |
| 39967 | 40237 | return pNew; |
| 39968 | 40238 | } |
| 39969 | 40239 | |
| 39970 | 40240 | /* |
| 39971 | 40241 | ** Decrement the reference count on a vxworksFileId object. Free |
| 39972 | 40242 | ** the object when the reference count reaches zero. |
| 39973 | 40243 | */ |
| 39974 | 40244 | static void vxworksReleaseFileId(struct vxworksFileId *pId){ |
| 39975 | - unixEnterMutex(); | |
| 40245 | + sqlite3_mutex_enter(vxworksMutex); | |
| 39976 | 40246 | assert( pId->nRef>0 ); |
| 39977 | 40247 | pId->nRef--; |
| 39978 | 40248 | if( pId->nRef==0 ){ |
| 39979 | 40249 | struct vxworksFileId **pp; |
| 39980 | 40250 | for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} |
| 39981 | 40251 | assert( *pp==pId ); |
| 39982 | 40252 | *pp = pId->pNext; |
| 39983 | 40253 | sqlite3_free(pId); |
| 39984 | 40254 | } |
| 39985 | - unixLeaveMutex(); | |
| 40255 | + sqlite3_mutex_leave(vxworksMutex); | |
| 39986 | 40256 | } |
| 39987 | 40257 | #endif /* OS_VXWORKS */ |
| 39988 | 40258 | /*************** End of Unique File ID Utility Used By VxWorks **************** |
| 39989 | 40259 | ******************************************************************************/ |
| 39990 | 40260 | |
| @@ -40368,10 +40638,14 @@ | ||
| 40368 | 40638 | do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); |
| 40369 | 40639 | if( rc!=1 ){ |
| 40370 | 40640 | storeLastErrno(pFile, errno); |
| 40371 | 40641 | return SQLITE_IOERR; |
| 40372 | 40642 | } |
| 40643 | + if( fsync(fd) ){ | |
| 40644 | + storeLastErrno(pFile, errno); | |
| 40645 | + return SQLITE_IOERR_FSYNC; | |
| 40646 | + } | |
| 40373 | 40647 | rc = osFstat(fd, &statbuf); |
| 40374 | 40648 | if( rc!=0 ){ |
| 40375 | 40649 | storeLastErrno(pFile, errno); |
| 40376 | 40650 | return SQLITE_IOERR; |
| 40377 | 40651 | } |
| @@ -40537,22 +40811,46 @@ | ||
| 40537 | 40811 | static int osSetPosixAdvisoryLock( |
| 40538 | 40812 | int h, /* The file descriptor on which to take the lock */ |
| 40539 | 40813 | struct flock *pLock, /* The description of the lock */ |
| 40540 | 40814 | unixFile *pFile /* Structure holding timeout value */ |
| 40541 | 40815 | ){ |
| 40542 | - int tm = pFile->iBusyTimeout; | |
| 40543 | - int rc = osFcntl(h,F_SETLK,pLock); | |
| 40544 | - while( rc<0 && tm>0 ){ | |
| 40545 | - /* On systems that support some kind of blocking file lock with a timeout, | |
| 40546 | - ** make appropriate changes here to invoke that blocking file lock. On | |
| 40547 | - ** generic posix, however, there is no such API. So we simply try the | |
| 40548 | - ** lock once every millisecond until either the timeout expires, or until | |
| 40549 | - ** the lock is obtained. */ | |
| 40550 | - unixSleep(0,1000); | |
| 40816 | + int rc = 0; | |
| 40817 | + | |
| 40818 | + if( pFile->iBusyTimeout==0 ){ | |
| 40819 | + /* unixFile->iBusyTimeout is set to 0. In this case, attempt a | |
| 40820 | + ** non-blocking lock. */ | |
| 40821 | + rc = osFcntl(h,F_SETLK,pLock); | |
| 40822 | + }else{ | |
| 40823 | + /* unixFile->iBusyTimeout is set to greater than zero. In this case, | |
| 40824 | + ** attempt a blocking-lock with a unixFile->iBusyTimeout ms timeout. | |
| 40825 | + ** | |
| 40826 | + ** On systems that support some kind of blocking file lock operation, | |
| 40827 | + ** this block should be replaced by code to attempt a blocking lock | |
| 40828 | + ** with a timeout of unixFile->iBusyTimeout ms. The code below is | |
| 40829 | + ** placeholder code. If SQLITE_TEST is defined, the placeholder code | |
| 40830 | + ** retries the lock once every 1ms until it succeeds or the timeout | |
| 40831 | + ** is reached. Or, if SQLITE_TEST is not defined, the placeholder | |
| 40832 | + ** code attempts a non-blocking lock and sets unixFile->iBusyTimeout | |
| 40833 | + ** to 0. This causes the caller to return SQLITE_BUSY, instead of | |
| 40834 | + ** SQLITE_BUSY_TIMEOUT to SQLite - as required by a VFS that does not | |
| 40835 | + ** support blocking locks. | |
| 40836 | + */ | |
| 40837 | +#ifdef SQLITE_TEST | |
| 40838 | + int tm = pFile->iBusyTimeout; | |
| 40839 | + while( tm>0 ){ | |
| 40840 | + rc = osFcntl(h,F_SETLK,pLock); | |
| 40841 | + if( rc==0 ) break; | |
| 40842 | + unixSleep(0,1000); | |
| 40843 | + tm--; | |
| 40844 | + } | |
| 40845 | +#else | |
| 40551 | 40846 | rc = osFcntl(h,F_SETLK,pLock); |
| 40552 | - tm--; | |
| 40847 | + pFile->iBusyTimeout = 0; | |
| 40848 | +#endif | |
| 40849 | + /* End of code to replace with real blocking-locks code. */ | |
| 40553 | 40850 | } |
| 40851 | + | |
| 40554 | 40852 | return rc; |
| 40555 | 40853 | } |
| 40556 | 40854 | #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ |
| 40557 | 40855 | |
| 40558 | 40856 | |
| @@ -44869,14 +45167,21 @@ | ||
| 44869 | 45167 | #endif |
| 44870 | 45168 | |
| 44871 | 45169 | storeLastErrno(pNew, 0); |
| 44872 | 45170 | #if OS_VXWORKS |
| 44873 | 45171 | if( rc!=SQLITE_OK ){ |
| 44874 | - if( h>=0 ) robust_close(pNew, h, __LINE__); | |
| 44875 | - h = -1; | |
| 44876 | - osUnlink(zFilename); | |
| 44877 | - pNew->ctrlFlags |= UNIXFILE_DELETE; | |
| 45172 | + if( h>=0 ){ | |
| 45173 | + robust_close(pNew, h, __LINE__); | |
| 45174 | + h = -1; | |
| 45175 | + } | |
| 45176 | + if( pNew->ctrlFlags & UNIXFILE_DELETE ){ | |
| 45177 | + osUnlink(zFilename); | |
| 45178 | + } | |
| 45179 | + if( pNew->pId ){ | |
| 45180 | + vxworksReleaseFileId(pNew->pId); | |
| 45181 | + pNew->pId = 0; | |
| 45182 | + } | |
| 44878 | 45183 | } |
| 44879 | 45184 | #endif |
| 44880 | 45185 | if( rc!=SQLITE_OK ){ |
| 44881 | 45186 | if( h>=0 ) robust_close(pNew, h, __LINE__); |
| 44882 | 45187 | }else{ |
| @@ -44916,10 +45221,13 @@ | ||
| 44916 | 45221 | struct stat buf; |
| 44917 | 45222 | const char *zDir = sqlite3_temp_directory; |
| 44918 | 45223 | |
| 44919 | 45224 | while(1){ |
| 44920 | 45225 | if( zDir!=0 |
| 45226 | +#if OS_VXWORKS | |
| 45227 | + && zDir[0]=='/' | |
| 45228 | +#endif | |
| 44921 | 45229 | && osStat(zDir, &buf)==0 |
| 44922 | 45230 | && S_ISDIR(buf.st_mode) |
| 44923 | 45231 | && osAccess(zDir, 03)==0 |
| 44924 | 45232 | ){ |
| 44925 | 45233 | return zDir; |
| @@ -45229,10 +45537,16 @@ | ||
| 45229 | 45537 | assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB |
| 45230 | 45538 | || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL |
| 45231 | 45539 | || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL |
| 45232 | 45540 | || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL |
| 45233 | 45541 | ); |
| 45542 | + | |
| 45543 | +#if OS_VXWORKS | |
| 45544 | + /* The file-ID mechanism used in Vxworks requires that all pathnames | |
| 45545 | + ** provided to unixOpen must be absolute pathnames. */ | |
| 45546 | + if( zPath!=0 && zPath[0]!='/' ){ return SQLITE_CANTOPEN; } | |
| 45547 | +#endif | |
| 45234 | 45548 | |
| 45235 | 45549 | /* Detect a pid change and reset the PRNG. There is a race condition |
| 45236 | 45550 | ** here such that two or more threads all trying to open databases at |
| 45237 | 45551 | ** the same instant might all reset the PRNG. But multiple resets |
| 45238 | 45552 | ** are harmless. |
| @@ -45430,12 +45744,15 @@ | ||
| 45430 | 45744 | goto open_finished; |
| 45431 | 45745 | } |
| 45432 | 45746 | } |
| 45433 | 45747 | #endif |
| 45434 | 45748 | |
| 45435 | - assert( zPath==0 || zPath[0]=='/' | |
| 45436 | - || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL | |
| 45749 | + assert( zPath==0 | |
| 45750 | + || zPath[0]=='/' | |
| 45751 | + || eType==SQLITE_OPEN_SUPER_JOURNAL | |
| 45752 | + || eType==SQLITE_OPEN_MAIN_JOURNAL | |
| 45753 | + || eType==SQLITE_OPEN_TEMP_JOURNAL | |
| 45437 | 45754 | ); |
| 45438 | 45755 | rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); |
| 45439 | 45756 | |
| 45440 | 45757 | open_finished: |
| 45441 | 45758 | if( rc!=SQLITE_OK ){ |
| @@ -47160,10 +47477,13 @@ | ||
| 47160 | 47477 | } |
| 47161 | 47478 | #ifdef SQLITE_OS_KV_OPTIONAL |
| 47162 | 47479 | sqlite3KvvfsInit(); |
| 47163 | 47480 | #endif |
| 47164 | 47481 | unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); |
| 47482 | +#if OS_VXWORKS | |
| 47483 | + vxworksMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS2); | |
| 47484 | +#endif | |
| 47165 | 47485 | |
| 47166 | 47486 | #ifndef SQLITE_OMIT_WAL |
| 47167 | 47487 | /* Validate lock assumptions */ |
| 47168 | 47488 | assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */ |
| 47169 | 47489 | assert( UNIX_SHM_BASE==120 ); /* Start of locking area */ |
| @@ -47194,10 +47514,13 @@ | ||
| 47194 | 47514 | ** to release dynamically allocated objects. But not on unix. |
| 47195 | 47515 | ** This routine is a no-op for unix. |
| 47196 | 47516 | */ |
| 47197 | 47517 | SQLITE_API int sqlite3_os_end(void){ |
| 47198 | 47518 | unixBigLock = 0; |
| 47519 | +#if OS_VXWORKS | |
| 47520 | + vxworksMutex = 0; | |
| 47521 | +#endif | |
| 47199 | 47522 | return SQLITE_OK; |
| 47200 | 47523 | } |
| 47201 | 47524 | |
| 47202 | 47525 | #endif /* SQLITE_OS_UNIX */ |
| 47203 | 47526 | |
| @@ -51192,204 +51515,10 @@ | ||
| 51192 | 51515 | ** on allocation size granularity boundaries. |
| 51193 | 51516 | ** During sqlite3_os_init() we do a GetSystemInfo() |
| 51194 | 51517 | ** to get the granularity size. |
| 51195 | 51518 | */ |
| 51196 | 51519 | static SYSTEM_INFO winSysInfo; |
| 51197 | - | |
| 51198 | -#ifndef SQLITE_OMIT_WAL | |
| 51199 | - | |
| 51200 | -/* | |
| 51201 | -** Helper functions to obtain and relinquish the global mutex. The | |
| 51202 | -** global mutex is used to protect the winLockInfo objects used by | |
| 51203 | -** this file, all of which may be shared by multiple threads. | |
| 51204 | -** | |
| 51205 | -** Function winShmMutexHeld() is used to assert() that the global mutex | |
| 51206 | -** is held when required. This function is only used as part of assert() | |
| 51207 | -** statements. e.g. | |
| 51208 | -** | |
| 51209 | -** winShmEnterMutex() | |
| 51210 | -** assert( winShmMutexHeld() ); | |
| 51211 | -** winShmLeaveMutex() | |
| 51212 | -*/ | |
| 51213 | -static sqlite3_mutex *winBigLock = 0; | |
| 51214 | -static void winShmEnterMutex(void){ | |
| 51215 | - sqlite3_mutex_enter(winBigLock); | |
| 51216 | -} | |
| 51217 | -static void winShmLeaveMutex(void){ | |
| 51218 | - sqlite3_mutex_leave(winBigLock); | |
| 51219 | -} | |
| 51220 | -#ifndef NDEBUG | |
| 51221 | -static int winShmMutexHeld(void) { | |
| 51222 | - return sqlite3_mutex_held(winBigLock); | |
| 51223 | -} | |
| 51224 | -#endif | |
| 51225 | - | |
| 51226 | -/* | |
| 51227 | -** Object used to represent a single file opened and mmapped to provide | |
| 51228 | -** shared memory. When multiple threads all reference the same | |
| 51229 | -** log-summary, each thread has its own winFile object, but they all | |
| 51230 | -** point to a single instance of this object. In other words, each | |
| 51231 | -** log-summary is opened only once per process. | |
| 51232 | -** | |
| 51233 | -** winShmMutexHeld() must be true when creating or destroying | |
| 51234 | -** this object or while reading or writing the following fields: | |
| 51235 | -** | |
| 51236 | -** nRef | |
| 51237 | -** pNext | |
| 51238 | -** | |
| 51239 | -** The following fields are read-only after the object is created: | |
| 51240 | -** | |
| 51241 | -** zFilename | |
| 51242 | -** | |
| 51243 | -** Either winShmNode.mutex must be held or winShmNode.nRef==0 and | |
| 51244 | -** winShmMutexHeld() is true when reading or writing any other field | |
| 51245 | -** in this structure. | |
| 51246 | -** | |
| 51247 | -** File-handle hSharedShm is used to (a) take the DMS lock, (b) truncate | |
| 51248 | -** the *-shm file if the DMS-locking protocol demands it, and (c) map | |
| 51249 | -** regions of the *-shm file into memory using MapViewOfFile() or | |
| 51250 | -** similar. Other locks are taken by individual clients using the | |
| 51251 | -** winShm.hShm handles. | |
| 51252 | -*/ | |
| 51253 | -struct winShmNode { | |
| 51254 | - sqlite3_mutex *mutex; /* Mutex to access this object */ | |
| 51255 | - char *zFilename; /* Name of the file */ | |
| 51256 | - HANDLE hSharedShm; /* File handle open on zFilename */ | |
| 51257 | - | |
| 51258 | - int isUnlocked; /* DMS lock has not yet been obtained */ | |
| 51259 | - int isReadonly; /* True if read-only */ | |
| 51260 | - int szRegion; /* Size of shared-memory regions */ | |
| 51261 | - int nRegion; /* Size of array apRegion */ | |
| 51262 | - | |
| 51263 | - struct ShmRegion { | |
| 51264 | - HANDLE hMap; /* File handle from CreateFileMapping */ | |
| 51265 | - void *pMap; | |
| 51266 | - } *aRegion; | |
| 51267 | - DWORD lastErrno; /* The Windows errno from the last I/O error */ | |
| 51268 | - | |
| 51269 | - int nRef; /* Number of winShm objects pointing to this */ | |
| 51270 | - winShmNode *pNext; /* Next in list of all winShmNode objects */ | |
| 51271 | -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) | |
| 51272 | - u8 nextShmId; /* Next available winShm.id value */ | |
| 51273 | -#endif | |
| 51274 | -}; | |
| 51275 | - | |
| 51276 | -/* | |
| 51277 | -** A global array of all winShmNode objects. | |
| 51278 | -** | |
| 51279 | -** The winShmMutexHeld() must be true while reading or writing this list. | |
| 51280 | -*/ | |
| 51281 | -static winShmNode *winShmNodeList = 0; | |
| 51282 | - | |
| 51283 | -/* | |
| 51284 | -** Structure used internally by this VFS to record the state of an | |
| 51285 | -** open shared memory connection. There is one such structure for each | |
| 51286 | -** winFile open on a wal mode database. | |
| 51287 | -*/ | |
| 51288 | -struct winShm { | |
| 51289 | - winShmNode *pShmNode; /* The underlying winShmNode object */ | |
| 51290 | - u16 sharedMask; /* Mask of shared locks held */ | |
| 51291 | - u16 exclMask; /* Mask of exclusive locks held */ | |
| 51292 | - HANDLE hShm; /* File-handle on *-shm file. For locking. */ | |
| 51293 | - int bReadonly; /* True if hShm is opened read-only */ | |
| 51294 | -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) | |
| 51295 | - u8 id; /* Id of this connection with its winShmNode */ | |
| 51296 | -#endif | |
| 51297 | -}; | |
| 51298 | - | |
| 51299 | -/* | |
| 51300 | -** Constants used for locking | |
| 51301 | -*/ | |
| 51302 | -#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ | |
| 51303 | -#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ | |
| 51304 | - | |
| 51305 | -/* Forward references to VFS methods */ | |
| 51306 | -static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); | |
| 51307 | -static int winDelete(sqlite3_vfs *,const char*,int); | |
| 51308 | - | |
| 51309 | -/* | |
| 51310 | -** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. | |
| 51311 | -** | |
| 51312 | -** This is not a VFS shared-memory method; it is a utility function called | |
| 51313 | -** by VFS shared-memory methods. | |
| 51314 | -*/ | |
| 51315 | -static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ | |
| 51316 | - winShmNode **pp; | |
| 51317 | - winShmNode *p; | |
| 51318 | - assert( winShmMutexHeld() ); | |
| 51319 | - OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", | |
| 51320 | - osGetCurrentProcessId(), deleteFlag)); | |
| 51321 | - pp = &winShmNodeList; | |
| 51322 | - while( (p = *pp)!=0 ){ | |
| 51323 | - if( p->nRef==0 ){ | |
| 51324 | - int i; | |
| 51325 | - if( p->mutex ){ sqlite3_mutex_free(p->mutex); } | |
| 51326 | - for(i=0; i<p->nRegion; i++){ | |
| 51327 | - BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); | |
| 51328 | - OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", | |
| 51329 | - osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); | |
| 51330 | - UNUSED_VARIABLE_VALUE(bRc); | |
| 51331 | - bRc = osCloseHandle(p->aRegion[i].hMap); | |
| 51332 | - OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", | |
| 51333 | - osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); | |
| 51334 | - UNUSED_VARIABLE_VALUE(bRc); | |
| 51335 | - } | |
| 51336 | - winHandleClose(p->hSharedShm); | |
| 51337 | - if( deleteFlag ){ | |
| 51338 | - SimulateIOErrorBenign(1); | |
| 51339 | - sqlite3BeginBenignMalloc(); | |
| 51340 | - winDelete(pVfs, p->zFilename, 0); | |
| 51341 | - sqlite3EndBenignMalloc(); | |
| 51342 | - SimulateIOErrorBenign(0); | |
| 51343 | - } | |
| 51344 | - *pp = p->pNext; | |
| 51345 | - sqlite3_free(p->aRegion); | |
| 51346 | - sqlite3_free(p); | |
| 51347 | - }else{ | |
| 51348 | - pp = &p->pNext; | |
| 51349 | - } | |
| 51350 | - } | |
| 51351 | -} | |
| 51352 | - | |
| 51353 | -/* | |
| 51354 | -** The DMS lock has not yet been taken on the shm file associated with | |
| 51355 | -** pShmNode. Take the lock. Truncate the *-shm file if required. | |
| 51356 | -** Return SQLITE_OK if successful, or an SQLite error code otherwise. | |
| 51357 | -*/ | |
| 51358 | -static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){ | |
| 51359 | - HANDLE h = pShmNode->hSharedShm; | |
| 51360 | - int rc = SQLITE_OK; | |
| 51361 | - | |
| 51362 | - assert( sqlite3_mutex_held(pShmNode->mutex) ); | |
| 51363 | - rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 1, 0); | |
| 51364 | - if( rc==SQLITE_OK ){ | |
| 51365 | - /* We have an EXCLUSIVE lock on the DMS byte. This means that this | |
| 51366 | - ** is the first process to open the file. Truncate it to zero bytes | |
| 51367 | - ** in this case. */ | |
| 51368 | - if( pShmNode->isReadonly ){ | |
| 51369 | - rc = SQLITE_READONLY_CANTINIT; | |
| 51370 | - }else{ | |
| 51371 | - rc = winHandleTruncate(h, 0); | |
| 51372 | - } | |
| 51373 | - | |
| 51374 | - /* Release the EXCLUSIVE lock acquired above. */ | |
| 51375 | - winUnlockFile(&h, WIN_SHM_DMS, 0, 1, 0); | |
| 51376 | - }else if( (rc & 0xFF)==SQLITE_BUSY ){ | |
| 51377 | - rc = SQLITE_OK; | |
| 51378 | - } | |
| 51379 | - | |
| 51380 | - if( rc==SQLITE_OK ){ | |
| 51381 | - /* Take a SHARED lock on the DMS byte. */ | |
| 51382 | - rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 0, nMs); | |
| 51383 | - if( rc==SQLITE_OK ){ | |
| 51384 | - pShmNode->isUnlocked = 0; | |
| 51385 | - } | |
| 51386 | - } | |
| 51387 | - | |
| 51388 | - return rc; | |
| 51389 | -} | |
| 51390 | - | |
| 51391 | 51520 | |
| 51392 | 51521 | /* |
| 51393 | 51522 | ** Convert a UTF-8 filename into whatever form the underlying |
| 51394 | 51523 | ** operating system wants filenames in. Space to hold the result |
| 51395 | 51524 | ** is obtained from malloc and must be freed by the calling |
| @@ -51483,10 +51612,212 @@ | ||
| 51483 | 51612 | } |
| 51484 | 51613 | #endif |
| 51485 | 51614 | /* caller will handle out of memory */ |
| 51486 | 51615 | return zConverted; |
| 51487 | 51616 | } |
| 51617 | + | |
| 51618 | +#ifndef SQLITE_OMIT_WAL | |
| 51619 | + | |
| 51620 | +/* | |
| 51621 | +** Helper functions to obtain and relinquish the global mutex. The | |
| 51622 | +** global mutex is used to protect the winLockInfo objects used by | |
| 51623 | +** this file, all of which may be shared by multiple threads. | |
| 51624 | +** | |
| 51625 | +** Function winShmMutexHeld() is used to assert() that the global mutex | |
| 51626 | +** is held when required. This function is only used as part of assert() | |
| 51627 | +** statements. e.g. | |
| 51628 | +** | |
| 51629 | +** winShmEnterMutex() | |
| 51630 | +** assert( winShmMutexHeld() ); | |
| 51631 | +** winShmLeaveMutex() | |
| 51632 | +*/ | |
| 51633 | +static sqlite3_mutex *winBigLock = 0; | |
| 51634 | +static void winShmEnterMutex(void){ | |
| 51635 | + sqlite3_mutex_enter(winBigLock); | |
| 51636 | +} | |
| 51637 | +static void winShmLeaveMutex(void){ | |
| 51638 | + sqlite3_mutex_leave(winBigLock); | |
| 51639 | +} | |
| 51640 | +#ifndef NDEBUG | |
| 51641 | +static int winShmMutexHeld(void) { | |
| 51642 | + return sqlite3_mutex_held(winBigLock); | |
| 51643 | +} | |
| 51644 | +#endif | |
| 51645 | + | |
| 51646 | +/* | |
| 51647 | +** Object used to represent a single file opened and mmapped to provide | |
| 51648 | +** shared memory. When multiple threads all reference the same | |
| 51649 | +** log-summary, each thread has its own winFile object, but they all | |
| 51650 | +** point to a single instance of this object. In other words, each | |
| 51651 | +** log-summary is opened only once per process. | |
| 51652 | +** | |
| 51653 | +** winShmMutexHeld() must be true when creating or destroying | |
| 51654 | +** this object, or while editing the global linked list that starts | |
| 51655 | +** at winShmNodeList. | |
| 51656 | +** | |
| 51657 | +** When reading or writing the linked list starting at winShmNode.pWinShmList, | |
| 51658 | +** pShmNode->mutex must be held. | |
| 51659 | +** | |
| 51660 | +** The following fields are constant after the object is created: | |
| 51661 | +** | |
| 51662 | +** zFilename | |
| 51663 | +** hSharedShm | |
| 51664 | +** mutex | |
| 51665 | +** bUseSharedLockHandle | |
| 51666 | +** | |
| 51667 | +** Either winShmNode.mutex must be held or winShmNode.pWinShmList==0 and | |
| 51668 | +** winShmMutexHeld() is true when reading or writing any other field | |
| 51669 | +** in this structure. | |
| 51670 | +** | |
| 51671 | +** File-handle hSharedShm is always used to (a) take the DMS lock, (b) | |
| 51672 | +** truncate the *-shm file if the DMS-locking protocol demands it, and | |
| 51673 | +** (c) map regions of the *-shm file into memory using MapViewOfFile() | |
| 51674 | +** or similar. If bUseSharedLockHandle is true, then other locks are also | |
| 51675 | +** taken on hSharedShm. Or, if bUseSharedLockHandle is false, then other | |
| 51676 | +** locks are taken using each connection's winShm.hShm handles. | |
| 51677 | +*/ | |
| 51678 | +struct winShmNode { | |