| | @@ -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 | | -** 22b2700ac20bb8e5883d484bfd0aee7a0fbc with changes in files: |
| 21 | +** 4966d7a1ce42af8b1c50fdd40e651e80d0ee with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -463,18 +463,18 @@ |
| 463 | 463 | ** been edited in any way since it was last checked in, then the last |
| 464 | 464 | ** four hexadecimal digits of the hash may be modified. |
| 465 | 465 | ** |
| 466 | 466 | ** See also: [sqlite3_libversion()], |
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 468 | | -** [sqlite_version()] and [sqlite_source_id()]. |
| 468 | +** [sqlite_version()] and [sqlite_sourceid()]. |
| 469 | 469 | */ |
| 470 | 470 | #define SQLITE_VERSION "3.51.0" |
| 471 | 471 | #define SQLITE_VERSION_NUMBER 3051000 |
| 472 | | -#define SQLITE_SOURCE_ID "2025-10-02 11:28:27 22b2700ac20bb8e5883d484bfd0aee7a0fbc99b92696d8ca850cd129e2ccbb43" |
| 472 | +#define SQLITE_SOURCE_ID "2025-10-10 14:31:46 4966d7a1ce42af8b1c50fdd40e651e80d0eeb8cb62dd882950cab275f98aba88" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2025-10-02T11:28:27.740Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2025-10-10T14:31:46.035Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -502,11 +502,11 @@ |
| 502 | 502 | ** a pointer to a string constant whose value is the same as the |
| 503 | 503 | ** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built |
| 504 | 504 | ** using an edited copy of [the amalgamation], then the last four characters |
| 505 | 505 | ** of the hash might be different from [SQLITE_SOURCE_ID].)^ |
| 506 | 506 | ** |
| 507 | | -** See also: [sqlite_version()] and [sqlite_source_id()]. |
| 507 | +** See also: [sqlite_version()] and [sqlite_sourceid()]. |
| 508 | 508 | */ |
| 509 | 509 | SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; |
| 510 | 510 | SQLITE_API const char *sqlite3_libversion(void); |
| 511 | 511 | SQLITE_API const char *sqlite3_sourceid(void); |
| 512 | 512 | SQLITE_API int sqlite3_libversion_number(void); |
| | @@ -11434,10 +11434,56 @@ |
| 11434 | 11434 | */ |
| 11435 | 11435 | #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ |
| 11436 | 11436 | #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ |
| 11437 | 11437 | #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ |
| 11438 | 11438 | |
| 11439 | +/* |
| 11440 | +** CAPI3REF: Bind array values to the CARRAY table-valued function |
| 11441 | +** |
| 11442 | +** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to |
| 11443 | +** one of the first argument of the [carray() table-valued function]. The |
| 11444 | +** S parameter is a pointer to the [prepared statement] that uses the carray() |
| 11445 | +** functions. I is the parameter index to be bound. P is a pointer to the |
| 11446 | +** array to be bound, and N is the number of eements in the array. The |
| 11447 | +** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], |
| 11448 | +** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to |
| 11449 | +** indicate the datatype of the array being bound. The X argument is not a |
| 11450 | +** NULL pointer, then SQLite will invoke the function X on the P parameter |
| 11451 | +** after it has finished using P. |
| 11452 | +*/ |
| 11453 | +SQLITE_API SQLITE_API int sqlite3_carray_bind( |
| 11454 | + sqlite3_stmt *pStmt, /* Statement to be bound */ |
| 11455 | + int i, /* Parameter index */ |
| 11456 | + void *aData, /* Pointer to array data */ |
| 11457 | + int nData, /* Number of data elements */ |
| 11458 | + int mFlags, /* CARRAY flags */ |
| 11459 | + void (*xDel)(void*) /* Destructor for aData */ |
| 11460 | +); |
| 11461 | + |
| 11462 | +/* |
| 11463 | +** CAPI3REF: Datatypes for the CARRAY table-valued funtion |
| 11464 | +** |
| 11465 | +** The fifth argument to the [sqlite3_carray_bind()] interface musts be |
| 11466 | +** one of the following constants, to specify the datatype of the array |
| 11467 | +** that is being bound into the [carray table-valued function]. |
| 11468 | +*/ |
| 11469 | +#define SQLITE_CARRAY_INT32 0 /* Data is 32-bit signed integers */ |
| 11470 | +#define SQLITE_CARRAY_INT64 1 /* Data is 64-bit signed integers */ |
| 11471 | +#define SQLITE_CARRAY_DOUBLE 2 /* Data is doubles */ |
| 11472 | +#define SQLITE_CARRAY_TEXT 3 /* Data is char* */ |
| 11473 | +#define SQLITE_CARRAY_BLOB 4 /* Data is struct iovec */ |
| 11474 | + |
| 11475 | +/* |
| 11476 | +** Versions of the above #defines that omit the initial SQLITE_, for |
| 11477 | +** legacy compatibility. |
| 11478 | +*/ |
| 11479 | +#define CARRAY_INT32 0 /* Data is 32-bit signed integers */ |
| 11480 | +#define CARRAY_INT64 1 /* Data is 64-bit signed integers */ |
| 11481 | +#define CARRAY_DOUBLE 2 /* Data is doubles */ |
| 11482 | +#define CARRAY_TEXT 3 /* Data is char* */ |
| 11483 | +#define CARRAY_BLOB 4 /* Data is struct iovec */ |
| 11484 | + |
| 11439 | 11485 | /* |
| 11440 | 11486 | ** Undo the hack that converts floating point types to integer for |
| 11441 | 11487 | ** builds on processors without floating point support. |
| 11442 | 11488 | */ |
| 11443 | 11489 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| | @@ -16013,12 +16059,12 @@ |
| 16013 | 16059 | ** |
| 16014 | 16060 | ** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application |
| 16015 | 16061 | ** must provide its own VFS implementation together with sqlite3_os_init() |
| 16016 | 16062 | ** and sqlite3_os_end() routines. |
| 16017 | 16063 | */ |
| 16018 | | -#if !defined(SQLITE_OS_KV) && !defined(SQLITE_OS_OTHER) && \ |
| 16019 | | - !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_WIN) |
| 16064 | +#if SQLITE_OS_KV+1<=1 && SQLITE_OS_OTHER+1<=1 && \ |
| 16065 | + SQLITE_OS_WIN+1<=1 && SQLITE_OS_UNIX+1<=1 |
| 16020 | 16066 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ |
| 16021 | 16067 | defined(__MINGW32__) || defined(__BORLANDC__) |
| 16022 | 16068 | # define SQLITE_OS_WIN 1 |
| 16023 | 16069 | # define SQLITE_OS_UNIX 0 |
| 16024 | 16070 | # else |
| | @@ -17516,10 +17562,13 @@ |
| 17516 | 17562 | #ifndef SQLITE_OMIT_TRACE |
| 17517 | 17563 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17518 | 17564 | #endif |
| 17519 | 17565 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17520 | 17566 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17567 | +#ifdef SQLITE_ENABLE_PERCENTILE |
| 17568 | +SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context*); |
| 17569 | +#endif |
| 17521 | 17570 | |
| 17522 | 17571 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); |
| 17523 | 17572 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17524 | 17573 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17525 | 17574 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| | @@ -21713,10 +21762,14 @@ |
| 21713 | 21762 | #endif |
| 21714 | 21763 | SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); |
| 21715 | 21764 | SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); |
| 21716 | 21765 | SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); |
| 21717 | 21766 | SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p); |
| 21767 | + |
| 21768 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) |
| 21769 | +SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3*); |
| 21770 | +#endif |
| 21718 | 21771 | |
| 21719 | 21772 | #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) |
| 21720 | 21773 | SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); |
| 21721 | 21774 | #endif |
| 21722 | 21775 | |
| | @@ -22699,10 +22752,13 @@ |
| 22699 | 22752 | #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE |
| 22700 | 22753 | "ENABLE_BATCH_ATOMIC_WRITE", |
| 22701 | 22754 | #endif |
| 22702 | 22755 | #ifdef SQLITE_ENABLE_BYTECODE_VTAB |
| 22703 | 22756 | "ENABLE_BYTECODE_VTAB", |
| 22757 | +#endif |
| 22758 | +#ifdef SQLITE_ENABLE_CARRAY |
| 22759 | + "ENABLE_CARRAY", |
| 22704 | 22760 | #endif |
| 22705 | 22761 | #ifdef SQLITE_ENABLE_CEROD |
| 22706 | 22762 | "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), |
| 22707 | 22763 | #endif |
| 22708 | 22764 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
| | @@ -22789,10 +22845,13 @@ |
| 22789 | 22845 | #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES |
| 22790 | 22846 | "ENABLE_ORDERED_SET_AGGREGATES", |
| 22791 | 22847 | #endif |
| 22792 | 22848 | #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK |
| 22793 | 22849 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 22850 | +#endif |
| 22851 | +#ifdef SQLITE_ENABLE_PERCENTILE |
| 22852 | + "ENABLE_PERCENTILE", |
| 22794 | 22853 | #endif |
| 22795 | 22854 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 22796 | 22855 | "ENABLE_PREUPDATE_HOOK", |
| 22797 | 22856 | #endif |
| 22798 | 22857 | #ifdef SQLITE_ENABLE_QPSG |
| | @@ -31850,56 +31909,74 @@ |
| 31850 | 31909 | etByte base; /* The base for radix conversion */ |
| 31851 | 31910 | etByte flags; /* One or more of FLAG_ constants below */ |
| 31852 | 31911 | etByte type; /* Conversion paradigm */ |
| 31853 | 31912 | etByte charset; /* Offset into aDigits[] of the digits string */ |
| 31854 | 31913 | etByte prefix; /* Offset into aPrefix[] of the prefix string */ |
| 31914 | + char iNxt; /* Next with same hash, or 0 for end of chain */ |
| 31855 | 31915 | } et_info; |
| 31856 | 31916 | |
| 31857 | 31917 | /* |
| 31858 | 31918 | ** Allowed values for et_info.flags |
| 31859 | 31919 | */ |
| 31860 | 31920 | #define FLAG_SIGNED 1 /* True if the value to convert is signed */ |
| 31861 | 31921 | #define FLAG_STRING 4 /* Allow infinite precision */ |
| 31862 | 31922 | |
| 31923 | +/* |
| 31924 | +** The table is searched by hash. In the case of %C where C is the character |
| 31925 | +** and that character has ASCII value j, then the hash is j%23. |
| 31926 | +** |
| 31927 | +** The order of the entries in fmtinfo[] and the hash chain was entered |
| 31928 | +** manually, but based on the output of the following TCL script: |
| 31929 | +*/ |
| 31930 | +#if 0 /***** Beginning of script ******/ |
| 31931 | +foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} { |
| 31932 | + scan $c %c x |
| 31933 | + set n($c) $x |
| 31934 | +} |
| 31935 | +set mx [llength [array names n]] |
| 31936 | +puts "count: $mx" |
| 31863 | 31937 | |
| 31864 | | -/* |
| 31865 | | -** The following table is searched linearly, so it is good to put the |
| 31866 | | -** most frequently used conversion types first. |
| 31867 | | -*/ |
| 31938 | +set mx 27 |
| 31939 | +puts "*********** mx=$mx ************" |
| 31940 | +for {set r 0} {$r<$mx} {incr r} { |
| 31941 | + puts -nonewline [format %2d: $r] |
| 31942 | + foreach c [array names n] { |
| 31943 | + if {($n($c))%$mx==$r} {puts -nonewline " $c"} |
| 31944 | + } |
| 31945 | + puts "" |
| 31946 | +} |
| 31947 | +#endif /***** End of script ********/ |
| 31948 | + |
| 31868 | 31949 | static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; |
| 31869 | 31950 | static const char aPrefix[] = "-x0\000X0"; |
| 31870 | | -static const et_info fmtinfo[] = { |
| 31871 | | - { 'd', 10, 1, etDECIMAL, 0, 0 }, |
| 31872 | | - { 's', 0, 4, etSTRING, 0, 0 }, |
| 31873 | | - { 'g', 0, 1, etGENERIC, 30, 0 }, |
| 31874 | | - { 'z', 0, 4, etDYNSTRING, 0, 0 }, |
| 31875 | | - { 'q', 0, 4, etESCAPE_q, 0, 0 }, |
| 31876 | | - { 'Q', 0, 4, etESCAPE_Q, 0, 0 }, |
| 31877 | | - { 'w', 0, 4, etESCAPE_w, 0, 0 }, |
| 31878 | | - { 'c', 0, 0, etCHARX, 0, 0 }, |
| 31879 | | - { 'o', 8, 0, etRADIX, 0, 2 }, |
| 31880 | | - { 'u', 10, 0, etDECIMAL, 0, 0 }, |
| 31881 | | - { 'x', 16, 0, etRADIX, 16, 1 }, |
| 31882 | | - { 'X', 16, 0, etRADIX, 0, 4 }, |
| 31883 | | -#ifndef SQLITE_OMIT_FLOATING_POINT |
| 31884 | | - { 'f', 0, 1, etFLOAT, 0, 0 }, |
| 31885 | | - { 'e', 0, 1, etEXP, 30, 0 }, |
| 31886 | | - { 'E', 0, 1, etEXP, 14, 0 }, |
| 31887 | | - { 'G', 0, 1, etGENERIC, 14, 0 }, |
| 31888 | | -#endif |
| 31889 | | - { 'i', 10, 1, etDECIMAL, 0, 0 }, |
| 31890 | | - { 'n', 0, 0, etSIZE, 0, 0 }, |
| 31891 | | - { '%', 0, 0, etPERCENT, 0, 0 }, |
| 31892 | | - { 'p', 16, 0, etPOINTER, 0, 1 }, |
| 31893 | | - |
| 31894 | | - /* All the rest are undocumented and are for internal use only */ |
| 31895 | | - { 'T', 0, 0, etTOKEN, 0, 0 }, |
| 31896 | | - { 'S', 0, 0, etSRCITEM, 0, 0 }, |
| 31897 | | - { 'r', 10, 1, etORDINAL, 0, 0 }, |
| 31951 | +static const et_info fmtinfo[23] = { |
| 31952 | + /* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 }, |
| 31953 | + /* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */ |
| 31954 | + /* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 }, |
| 31955 | + /* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */ |
| 31956 | + /* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, |
| 31957 | + /* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, |
| 31958 | + /* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */ |
| 31959 | + /* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 }, |
| 31960 | + /* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, |
| 31961 | + /* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, |
| 31962 | + /* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, |
| 31963 | + /* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, |
| 31964 | + /* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 }, |
| 31965 | + /* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, |
| 31966 | + /* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 }, |
| 31967 | + /* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, |
| 31968 | + /* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */ |
| 31969 | + /* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */ |
| 31970 | + /* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, |
| 31971 | + /* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 }, |
| 31972 | + /* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, |
| 31973 | + /* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 }, |
| 31974 | + /* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 } |
| 31898 | 31975 | }; |
| 31899 | 31976 | |
| 31900 | | -/* Notes: |
| 31977 | +/* Additional Notes: |
| 31901 | 31978 | ** |
| 31902 | 31979 | ** %S Takes a pointer to SrcItem. Shows name or database.name |
| 31903 | 31980 | ** %!S Like %S but prefer the zName over the zAlias |
| 31904 | 31981 | */ |
| 31905 | 31982 | |
| | @@ -32022,11 +32099,14 @@ |
| 32022 | 32099 | if( c!='%' ){ |
| 32023 | 32100 | bufpt = (char *)fmt; |
| 32024 | 32101 | #if HAVE_STRCHRNUL |
| 32025 | 32102 | fmt = strchrnul(fmt, '%'); |
| 32026 | 32103 | #else |
| 32027 | | - do{ fmt++; }while( *fmt && *fmt != '%' ); |
| 32104 | + fmt = strchr(fmt, '%'); |
| 32105 | + if( fmt==0 ){ |
| 32106 | + fmt = bufpt + strlen(bufpt); |
| 32107 | + } |
| 32028 | 32108 | #endif |
| 32029 | 32109 | sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); |
| 32030 | 32110 | if( *fmt==0 ) break; |
| 32031 | 32111 | } |
| 32032 | 32112 | if( (c=(*++fmt))==0 ){ |
| | @@ -32136,19 +32216,36 @@ |
| 32136 | 32216 | } |
| 32137 | 32217 | } |
| 32138 | 32218 | }while( !done && (c=(*++fmt))!=0 ); |
| 32139 | 32219 | |
| 32140 | 32220 | /* Fetch the info entry for the field */ |
| 32221 | +#ifdef SQLITE_EBCDIC |
| 32222 | + /* The hash table only works for ASCII. For EBCDIC, we need to do |
| 32223 | + ** a linear search of the table */ |
| 32141 | 32224 | infop = &fmtinfo[0]; |
| 32142 | 32225 | xtype = etINVALID; |
| 32143 | 32226 | for(idx=0; idx<ArraySize(fmtinfo); idx++){ |
| 32144 | 32227 | if( c==fmtinfo[idx].fmttype ){ |
| 32145 | 32228 | infop = &fmtinfo[idx]; |
| 32146 | 32229 | xtype = infop->type; |
| 32147 | 32230 | break; |
| 32148 | 32231 | } |
| 32149 | 32232 | } |
| 32233 | +#else |
| 32234 | + /* Fast hash-table lookup */ |
| 32235 | + assert( ArraySize(fmtinfo)==23 ); |
| 32236 | + idx = ((unsigned)c) % 23; |
| 32237 | + if( fmtinfo[idx].fmttype==c |
| 32238 | + || fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c |
| 32239 | + ){ |
| 32240 | + infop = &fmtinfo[idx]; |
| 32241 | + xtype = infop->type; |
| 32242 | + }else{ |
| 32243 | + infop = &fmtinfo[0]; |
| 32244 | + xtype = etINVALID; |
| 32245 | + } |
| 32246 | +#endif |
| 32150 | 32247 | |
| 32151 | 32248 | /* |
| 32152 | 32249 | ** At this point, variables are initialized as follows: |
| 32153 | 32250 | ** |
| 32154 | 32251 | ** flag_alternateform TRUE if a '#' is present. |
| | @@ -91918,10 +92015,21 @@ |
| 91918 | 92015 | sqlite3DbFree(db, preupdate.apDflt); |
| 91919 | 92016 | } |
| 91920 | 92017 | } |
| 91921 | 92018 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ |
| 91922 | 92019 | |
| 92020 | +#ifdef SQLITE_ENABLE_PERCENTILE |
| 92021 | +/* |
| 92022 | +** Return the name of an SQL function associated with the sqlite3_context. |
| 92023 | +*/ |
| 92024 | +SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context *pCtx){ |
| 92025 | + assert( pCtx!=0 ); |
| 92026 | + assert( pCtx->pFunc!=0 ); |
| 92027 | + return pCtx->pFunc->zName; |
| 92028 | +} |
| 92029 | +#endif /* SQLITE_ENABLE_PERCENTILE */ |
| 92030 | + |
| 91923 | 92031 | /************** End of vdbeaux.c *********************************************/ |
| 91924 | 92032 | /************** Begin file vdbeapi.c *****************************************/ |
| 91925 | 92033 | /* |
| 91926 | 92034 | ** 2004 May 26 |
| 91927 | 92035 | ** |
| | @@ -93615,12 +93723,16 @@ |
| 93615 | 93723 | if( rc==SQLITE_OK ){ |
| 93616 | 93724 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ |
| 93617 | 93725 | if( zData!=0 ){ |
| 93618 | 93726 | pVar = &p->aVar[i-1]; |
| 93619 | 93727 | rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); |
| 93620 | | - if( rc==SQLITE_OK && encoding!=0 ){ |
| 93621 | | - rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); |
| 93728 | + if( rc==SQLITE_OK ){ |
| 93729 | + if( encoding==0 ){ |
| 93730 | + pVar->enc = ENC(p->db); |
| 93731 | + }else{ |
| 93732 | + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); |
| 93733 | + } |
| 93622 | 93734 | } |
| 93623 | 93735 | if( rc ){ |
| 93624 | 93736 | sqlite3Error(p->db, rc); |
| 93625 | 93737 | rc = sqlite3ApiExit(p->db, rc); |
| 93626 | 93738 | } |
| | @@ -115764,16 +115876,18 @@ |
| 115764 | 115876 | assert( pExpr!=0 ); |
| 115765 | 115877 | op = pExpr->op; |
| 115766 | 115878 | assert( op==TK_AND || op==TK_OR ); |
| 115767 | 115879 | assert( TK_AND==OP_And ); testcase( op==TK_AND ); |
| 115768 | 115880 | assert( TK_OR==OP_Or ); testcase( op==TK_OR ); |
| 115881 | + assert( pParse->pVdbe!=0 ); |
| 115882 | + v = pParse->pVdbe; |
| 115769 | 115883 | pAlt = sqlite3ExprSimplifiedAndOr(pExpr); |
| 115770 | 115884 | if( pAlt!=pExpr ){ |
| 115771 | | - return sqlite3ExprCodeTarget(pParse, pAlt, target); |
| 115885 | + r1 = sqlite3ExprCodeTarget(pParse, pAlt, target); |
| 115886 | + sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, target); |
| 115887 | + return target; |
| 115772 | 115888 | } |
| 115773 | | - assert( pParse->pVdbe!=0 ); |
| 115774 | | - v = pParse->pVdbe; |
| 115775 | 115889 | skipOp = op==TK_AND ? OP_IfNot : OP_If; |
| 115776 | 115890 | if( exprEvalRhsFirst(pExpr) ){ |
| 115777 | 115891 | /* Compute the right operand first. Skip the computation of the left |
| 115778 | 115892 | ** operand if the right operand fully determines the result */ |
| 115779 | 115893 | r2 = regSS = sqlite3ExprCodeTarget(pParse, pExpr->pRight, target); |
| | @@ -124266,10 +124380,15 @@ |
| 124266 | 124380 | } |
| 124267 | 124381 | #ifndef SQLITE_OMIT_JSON |
| 124268 | 124382 | if( pMod==0 && sqlite3_strnicmp(zName, "json", 4)==0 ){ |
| 124269 | 124383 | pMod = sqlite3JsonVtabRegister(db, zName); |
| 124270 | 124384 | } |
| 124385 | +#endif |
| 124386 | +#ifdef SQLITE_ENABLE_CARRAY |
| 124387 | + if( pMod==0 && sqlite3_stricmp(zName, "carray")==0 ){ |
| 124388 | + pMod = sqlite3CarrayRegister(db); |
| 124389 | + } |
| 124271 | 124390 | #endif |
| 124272 | 124391 | if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ |
| 124273 | 124392 | testcase( pMod->pEpoTab==0 ); |
| 124274 | 124393 | return pMod->pEpoTab; |
| 124275 | 124394 | } |
| | @@ -132380,11 +132499,11 @@ |
| 132380 | 132499 | ** a decoding of those digits into *pVal. Or return false if any |
| 132381 | 132500 | ** one of the first N characters in z[] is not a hexadecimal digit. |
| 132382 | 132501 | */ |
| 132383 | 132502 | static int isNHex(const char *z, int N, u32 *pVal){ |
| 132384 | 132503 | int i; |
| 132385 | | - int v = 0; |
| 132504 | + u32 v = 0; |
| 132386 | 132505 | for(i=0; i<N; i++){ |
| 132387 | 132506 | if( !sqlite3Isxdigit(z[i]) ) return 0; |
| 132388 | 132507 | v = (v<<4) + sqlite3HexToInt(z[i]); |
| 132389 | 132508 | } |
| 132390 | 132509 | *pVal = v; |
| | @@ -133859,10 +133978,456 @@ |
| 133859 | 133978 | type0 = sqlite3_value_numeric_type(argv[0]); |
| 133860 | 133979 | if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; |
| 133861 | 133980 | x = sqlite3_value_double(argv[0]); |
| 133862 | 133981 | sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); |
| 133863 | 133982 | } |
| 133983 | + |
| 133984 | +#if defined(SQLITE_ENABLE_PERCENTILE) |
| 133985 | +/*********************************************************************** |
| 133986 | +** This section implements the percentile(Y,P) SQL function and similar. |
| 133987 | +** Requirements: |
| 133988 | +** |
| 133989 | +** (1) The percentile(Y,P) function is an aggregate function taking |
| 133990 | +** exactly two arguments. |
| 133991 | +** |
| 133992 | +** (2) If the P argument to percentile(Y,P) is not the same for every |
| 133993 | +** row in the aggregate then an error is thrown. The word "same" |
| 133994 | +** in the previous sentence means that the value differ by less |
| 133995 | +** than 0.001. |
| 133996 | +** |
| 133997 | +** (3) If the P argument to percentile(Y,P) evaluates to anything other |
| 133998 | +** than a number in the range of 0.0 to 100.0 inclusive then an |
| 133999 | +** error is thrown. |
| 134000 | +** |
| 134001 | +** (4) If any Y argument to percentile(Y,P) evaluates to a value that |
| 134002 | +** is not NULL and is not numeric then an error is thrown. |
| 134003 | +** |
| 134004 | +** (5) If any Y argument to percentile(Y,P) evaluates to plus or minus |
| 134005 | +** infinity then an error is thrown. (SQLite always interprets NaN |
| 134006 | +** values as NULL.) |
| 134007 | +** |
| 134008 | +** (6) Both Y and P in percentile(Y,P) can be arbitrary expressions, |
| 134009 | +** including CASE WHEN expressions. |
| 134010 | +** |
| 134011 | +** (7) The percentile(Y,P) aggregate is able to handle inputs of at least |
| 134012 | +** one million (1,000,000) rows. |
| 134013 | +** |
| 134014 | +** (8) If there are no non-NULL values for Y, then percentile(Y,P) |
| 134015 | +** returns NULL. |
| 134016 | +** |
| 134017 | +** (9) If there is exactly one non-NULL value for Y, the percentile(Y,P) |
| 134018 | +** returns the one Y value. |
| 134019 | +** |
| 134020 | +** (10) If there N non-NULL values of Y where N is two or more and |
| 134021 | +** the Y values are ordered from least to greatest and a graph is |
| 134022 | +** drawn from 0 to N-1 such that the height of the graph at J is |
| 134023 | +** the J-th Y value and such that straight lines are drawn between |
| 134024 | +** adjacent Y values, then the percentile(Y,P) function returns |
| 134025 | +** the height of the graph at P*(N-1)/100. |
| 134026 | +** |
| 134027 | +** (11) The percentile(Y,P) function always returns either a floating |
| 134028 | +** point number or NULL. |
| 134029 | +** |
| 134030 | +** (12) The percentile(Y,P) is implemented as a single C99 source-code |
| 134031 | +** file that compiles into a shared-library or DLL that can be loaded |
| 134032 | +** into SQLite using the sqlite3_load_extension() interface. |
| 134033 | +** |
| 134034 | +** (13) A separate median(Y) function is the equivalent percentile(Y,50). |
| 134035 | +** |
| 134036 | +** (14) A separate percentile_cont(Y,P) function is equivalent to |
| 134037 | +** percentile(Y,P/100.0). In other words, the fraction value in |
| 134038 | +** the second argument is in the range of 0 to 1 instead of 0 to 100. |
| 134039 | +** |
| 134040 | +** (15) A separate percentile_disc(Y,P) function is like |
| 134041 | +** percentile_cont(Y,P) except that instead of returning the weighted |
| 134042 | +** average of the nearest two input values, it returns the next lower |
| 134043 | +** value. So the percentile_disc(Y,P) will always return a value |
| 134044 | +** that was one of the inputs. |
| 134045 | +** |
| 134046 | +** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and |
| 134047 | +** percentile_disc(Y,P) can be used as window functions. |
| 134048 | +** |
| 134049 | +** Differences from standard SQL: |
| 134050 | +** |
| 134051 | +** * The percentile_cont(X,P) function is equivalent to the following in |
| 134052 | +** standard SQL: |
| 134053 | +** |
| 134054 | +** (percentile_cont(P) WITHIN GROUP (ORDER BY X)) |
| 134055 | +** |
| 134056 | +** The SQLite syntax is much more compact. The standard SQL syntax |
| 134057 | +** is also supported if SQLite is compiled with the |
| 134058 | +** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option. |
| 134059 | +** |
| 134060 | +** * No median(X) function exists in the SQL standard. App developers |
| 134061 | +** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)". |
| 134062 | +** |
| 134063 | +** * No percentile(Y,P) function exists in the SQL standard. Instead of |
| 134064 | +** percential(Y,P), developers must write this: |
| 134065 | +** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that |
| 134066 | +** the fraction parameter to percentile() goes from 0 to 100 whereas |
| 134067 | +** the fraction parameter in SQL standard percentile_cont() goes from |
| 134068 | +** 0 to 1. |
| 134069 | +** |
| 134070 | +** Implementation notes as of 2024-08-31: |
| 134071 | +** |
| 134072 | +** * The regular aggregate-function versions of these routines work |
| 134073 | +** by accumulating all values in an array of doubles, then sorting |
| 134074 | +** that array using quicksort before computing the answer. Thus |
| 134075 | +** the runtime is O(NlogN) where N is the number of rows of input. |
| 134076 | +** |
| 134077 | +** * For the window-function versions of these routines, the array of |
| 134078 | +** inputs is sorted as soon as the first value is computed. Thereafter, |
| 134079 | +** the array is kept in sorted order using an insert-sort. This |
| 134080 | +** results in O(N*K) performance where K is the size of the window. |
| 134081 | +** One can imagine alternative implementations that give O(N*logN*logK) |
| 134082 | +** performance, but they require more complex logic and data structures. |
| 134083 | +** The developers have elected to keep the asymptotically slower |
| 134084 | +** algorithm for now, for simplicity, under the theory that window |
| 134085 | +** functions are seldom used and when they are, the window size K is |
| 134086 | +** often small. The developers might revisit that decision later, |
| 134087 | +** should the need arise. |
| 134088 | +*/ |
| 134089 | + |
| 134090 | +/* The following object is the group context for a single percentile() |
| 134091 | +** aggregate. Remember all input Y values until the very end. |
| 134092 | +** Those values are accumulated in the Percentile.a[] array. |
| 134093 | +*/ |
| 134094 | +typedef struct Percentile Percentile; |
| 134095 | +struct Percentile { |
| 134096 | + unsigned nAlloc; /* Number of slots allocated for a[] */ |
| 134097 | + unsigned nUsed; /* Number of slots actually used in a[] */ |
| 134098 | + char bSorted; /* True if a[] is already in sorted order */ |
| 134099 | + char bKeepSorted; /* True if advantageous to keep a[] sorted */ |
| 134100 | + char bPctValid; /* True if rPct is valid */ |
| 134101 | + double rPct; /* Fraction. 0.0 to 1.0 */ |
| 134102 | + double *a; /* Array of Y values */ |
| 134103 | +}; |
| 134104 | + |
| 134105 | +/* |
| 134106 | +** Return TRUE if the input floating-point number is an infinity. |
| 134107 | +*/ |
| 134108 | +static int percentIsInfinity(double r){ |
| 134109 | + sqlite3_uint64 u; |
| 134110 | + assert( sizeof(u)==sizeof(r) ); |
| 134111 | + memcpy(&u, &r, sizeof(u)); |
| 134112 | + return ((u>>52)&0x7ff)==0x7ff; |
| 134113 | +} |
| 134114 | + |
| 134115 | +/* |
| 134116 | +** Return TRUE if two doubles differ by 0.001 or less. |
| 134117 | +*/ |
| 134118 | +static int percentSameValue(double a, double b){ |
| 134119 | + a -= b; |
| 134120 | + return a>=-0.001 && a<=0.001; |
| 134121 | +} |
| 134122 | + |
| 134123 | +/* |
| 134124 | +** Search p (which must have p->bSorted) looking for an entry with |
| 134125 | +** value y. Return the index of that entry. |
| 134126 | +** |
| 134127 | +** If bExact is true, return -1 if the entry is not found. |
| 134128 | +** |
| 134129 | +** If bExact is false, return the index at which a new entry with |
| 134130 | +** value y should be insert in order to keep the values in sorted |
| 134131 | +** order. The smallest return value in this case will be 0, and |
| 134132 | +** the largest return value will be p->nUsed. |
| 134133 | +*/ |
| 134134 | +static int percentBinarySearch(Percentile *p, double y, int bExact){ |
| 134135 | + int iFirst = 0; /* First element of search range */ |
| 134136 | + int iLast = p->nUsed - 1; /* Last element of search range */ |
| 134137 | + while( iLast>=iFirst ){ |
| 134138 | + int iMid = (iFirst+iLast)/2; |
| 134139 | + double x = p->a[iMid]; |
| 134140 | + if( x<y ){ |
| 134141 | + iFirst = iMid + 1; |
| 134142 | + }else if( x>y ){ |
| 134143 | + iLast = iMid - 1; |
| 134144 | + }else{ |
| 134145 | + return iMid; |
| 134146 | + } |
| 134147 | + } |
| 134148 | + if( bExact ) return -1; |
| 134149 | + return iFirst; |
| 134150 | +} |
| 134151 | + |
| 134152 | +/* |
| 134153 | +** Generate an error for a percentile function. |
| 134154 | +** |
| 134155 | +** The error format string must have exactly one occurrence of "%%s()" |
| 134156 | +** (with two '%' characters). That substring will be replaced by the name |
| 134157 | +** of the function. |
| 134158 | +*/ |
| 134159 | +static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ |
| 134160 | + char *zMsg1; |
| 134161 | + char *zMsg2; |
| 134162 | + va_list ap; |
| 134163 | + |
| 134164 | + va_start(ap, zFormat); |
| 134165 | + zMsg1 = sqlite3_vmprintf(zFormat, ap); |
| 134166 | + va_end(ap); |
| 134167 | + zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, sqlite3VdbeFuncName(pCtx)) : 0; |
| 134168 | + sqlite3_result_error(pCtx, zMsg2, -1); |
| 134169 | + sqlite3_free(zMsg1); |
| 134170 | + sqlite3_free(zMsg2); |
| 134171 | +} |
| 134172 | + |
| 134173 | +/* |
| 134174 | +** The "step" function for percentile(Y,P) is called once for each |
| 134175 | +** input row. |
| 134176 | +*/ |
| 134177 | +static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ |
| 134178 | + Percentile *p; |
| 134179 | + double rPct; |
| 134180 | + int eType; |
| 134181 | + double y; |
| 134182 | + assert( argc==2 || argc==1 ); |
| 134183 | + |
| 134184 | + if( argc==1 ){ |
| 134185 | + /* Requirement 13: median(Y) is the same as percentile(Y,50). */ |
| 134186 | + rPct = 0.5; |
| 134187 | + }else{ |
| 134188 | + /* P must be a number between 0 and 100 for percentile() or between |
| 134189 | + ** 0.0 and 1.0 for percentile_cont() and percentile_disc(). |
| 134190 | + ** |
| 134191 | + ** The user-data is an integer which is 10 times the upper bound. |
| 134192 | + */ |
| 134193 | + double mxFrac = (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx))&2)? 100.0 : 1.0; |
| 134194 | + eType = sqlite3_value_numeric_type(argv[1]); |
| 134195 | + rPct = sqlite3_value_double(argv[1])/mxFrac; |
| 134196 | + if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) |
| 134197 | + || rPct<0.0 || rPct>1.0 |
| 134198 | + ){ |
| 134199 | + percentError(pCtx, "the fraction argument to %%s()" |
| 134200 | + " is not between 0.0 and %.1f", |
| 134201 | + (double)mxFrac); |
| 134202 | + return; |
| 134203 | + } |
| 134204 | + } |
| 134205 | + |
| 134206 | + /* Allocate the session context. */ |
| 134207 | + p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 134208 | + if( p==0 ) return; |
| 134209 | + |
| 134210 | + /* Remember the P value. Throw an error if the P value is different |
| 134211 | + ** from any prior row, per Requirement (2). */ |
| 134212 | + if( !p->bPctValid ){ |
| 134213 | + p->rPct = rPct; |
| 134214 | + p->bPctValid = 1; |
| 134215 | + }else if( !percentSameValue(p->rPct,rPct) ){ |
| 134216 | + percentError(pCtx, "the fraction argument to %%s()" |
| 134217 | + " is not the same for all input rows"); |
| 134218 | + return; |
| 134219 | + } |
| 134220 | + |
| 134221 | + /* Ignore rows for which Y is NULL */ |
| 134222 | + eType = sqlite3_value_type(argv[0]); |
| 134223 | + if( eType==SQLITE_NULL ) return; |
| 134224 | + |
| 134225 | + /* If not NULL, then Y must be numeric. Otherwise throw an error. |
| 134226 | + ** Requirement 4 */ |
| 134227 | + if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ |
| 134228 | + percentError(pCtx, "input to %%s() is not numeric"); |
| 134229 | + return; |
| 134230 | + } |
| 134231 | + |
| 134232 | + /* Throw an error if the Y value is infinity or NaN */ |
| 134233 | + y = sqlite3_value_double(argv[0]); |
| 134234 | + if( percentIsInfinity(y) ){ |
| 134235 | + percentError(pCtx, "Inf input to %%s()"); |
| 134236 | + return; |
| 134237 | + } |
| 134238 | + |
| 134239 | + /* Allocate and store the Y */ |
| 134240 | + if( p->nUsed>=p->nAlloc ){ |
| 134241 | + unsigned n = p->nAlloc*2 + 250; |
| 134242 | + double *a = sqlite3_realloc64(p->a, sizeof(double)*n); |
| 134243 | + if( a==0 ){ |
| 134244 | + sqlite3_free(p->a); |
| 134245 | + memset(p, 0, sizeof(*p)); |
| 134246 | + sqlite3_result_error_nomem(pCtx); |
| 134247 | + return; |
| 134248 | + } |
| 134249 | + p->nAlloc = n; |
| 134250 | + p->a = a; |
| 134251 | + } |
| 134252 | + if( p->nUsed==0 ){ |
| 134253 | + p->a[p->nUsed++] = y; |
| 134254 | + p->bSorted = 1; |
| 134255 | + }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){ |
| 134256 | + p->a[p->nUsed++] = y; |
| 134257 | + }else if( p->bKeepSorted ){ |
| 134258 | + int i; |
| 134259 | + i = percentBinarySearch(p, y, 0); |
| 134260 | + if( i<(int)p->nUsed ){ |
| 134261 | + memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0])); |
| 134262 | + } |
| 134263 | + p->a[i] = y; |
| 134264 | + p->nUsed++; |
| 134265 | + }else{ |
| 134266 | + p->a[p->nUsed++] = y; |
| 134267 | + p->bSorted = 0; |
| 134268 | + } |
| 134269 | +} |
| 134270 | + |
| 134271 | +/* |
| 134272 | +** Interchange two doubles. |
| 134273 | +*/ |
| 134274 | +#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} |
| 134275 | + |
| 134276 | +/* |
| 134277 | +** Sort an array of doubles. |
| 134278 | +** |
| 134279 | +** Algorithm: quicksort |
| 134280 | +** |
| 134281 | +** This is implemented separately rather than using the qsort() routine |
| 134282 | +** from the standard library because: |
| 134283 | +** |
| 134284 | +** (1) To avoid a dependency on qsort() |
| 134285 | +** (2) To avoid the function call to the comparison routine for each |
| 134286 | +** comparison. |
| 134287 | +*/ |
| 134288 | +static void percentSort(double *a, unsigned int n){ |
| 134289 | + int iLt; /* Entries before a[iLt] are less than rPivot */ |
| 134290 | + int iGt; /* Entries at or after a[iGt] are greater than rPivot */ |
| 134291 | + int i; /* Loop counter */ |
| 134292 | + double rPivot; /* The pivot value */ |
| 134293 | + |
| 134294 | + assert( n>=2 ); |
| 134295 | + if( a[0]>a[n-1] ){ |
| 134296 | + SWAP_DOUBLE(a[0],a[n-1]) |
| 134297 | + } |
| 134298 | + if( n==2 ) return; |
| 134299 | + iGt = n-1; |
| 134300 | + i = n/2; |
| 134301 | + if( a[0]>a[i] ){ |
| 134302 | + SWAP_DOUBLE(a[0],a[i]) |
| 134303 | + }else if( a[i]>a[iGt] ){ |
| 134304 | + SWAP_DOUBLE(a[i],a[iGt]) |
| 134305 | + } |
| 134306 | + if( n==3 ) return; |
| 134307 | + rPivot = a[i]; |
| 134308 | + iLt = i = 1; |
| 134309 | + do{ |
| 134310 | + if( a[i]<rPivot ){ |
| 134311 | + if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt]) |
| 134312 | + iLt++; |
| 134313 | + i++; |
| 134314 | + }else if( a[i]>rPivot ){ |
| 134315 | + do{ |
| 134316 | + iGt--; |
| 134317 | + }while( iGt>i && a[iGt]>rPivot ); |
| 134318 | + SWAP_DOUBLE(a[i],a[iGt]) |
| 134319 | + }else{ |
| 134320 | + i++; |
| 134321 | + } |
| 134322 | + }while( i<iGt ); |
| 134323 | + if( iLt>=2 ) percentSort(a, iLt); |
| 134324 | + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); |
| 134325 | + |
| 134326 | +/* Uncomment for testing */ |
| 134327 | +#if 0 |
| 134328 | + for(i=0; i<n-1; i++){ |
| 134329 | + assert( a[i]<=a[i+1] ); |
| 134330 | + } |
| 134331 | +#endif |
| 134332 | +} |
| 134333 | + |
| 134334 | + |
| 134335 | +/* |
| 134336 | +** The "inverse" function for percentile(Y,P) is called to remove a |
| 134337 | +** row that was previously inserted by "step". |
| 134338 | +*/ |
| 134339 | +static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){ |
| 134340 | + Percentile *p; |
| 134341 | + int eType; |
| 134342 | + double y; |
| 134343 | + int i; |
| 134344 | + assert( argc==2 || argc==1 ); |
| 134345 | + |
| 134346 | + /* Allocate the session context. */ |
| 134347 | + p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 134348 | + assert( p!=0 ); |
| 134349 | + |
| 134350 | + /* Ignore rows for which Y is NULL */ |
| 134351 | + eType = sqlite3_value_type(argv[0]); |
| 134352 | + if( eType==SQLITE_NULL ) return; |
| 134353 | + |
| 134354 | + /* If not NULL, then Y must be numeric. Otherwise throw an error. |
| 134355 | + ** Requirement 4 */ |
| 134356 | + if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ |
| 134357 | + return; |
| 134358 | + } |
| 134359 | + |
| 134360 | + /* Ignore the Y value if it is infinity or NaN */ |
| 134361 | + y = sqlite3_value_double(argv[0]); |
| 134362 | + if( percentIsInfinity(y) ){ |
| 134363 | + return; |
| 134364 | + } |
| 134365 | + if( p->bSorted==0 ){ |
| 134366 | + assert( p->nUsed>1 ); |
| 134367 | + percentSort(p->a, p->nUsed); |
| 134368 | + p->bSorted = 1; |
| 134369 | + } |
| 134370 | + p->bKeepSorted = 1; |
| 134371 | + |
| 134372 | + /* Find and remove the row */ |
| 134373 | + i = percentBinarySearch(p, y, 1); |
| 134374 | + if( i>=0 ){ |
| 134375 | + p->nUsed--; |
| 134376 | + if( i<(int)p->nUsed ){ |
| 134377 | + memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0])); |
| 134378 | + } |
| 134379 | + } |
| 134380 | +} |
| 134381 | + |
| 134382 | +/* |
| 134383 | +** Compute the final output of percentile(). Clean up all allocated |
| 134384 | +** memory if and only if bIsFinal is true. |
| 134385 | +*/ |
| 134386 | +static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ |
| 134387 | + Percentile *p; |
| 134388 | + int settings = SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx))&1; /* Discrete? */ |
| 134389 | + unsigned i1, i2; |
| 134390 | + double v1, v2; |
| 134391 | + double ix, vx; |
| 134392 | + p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); |
| 134393 | + if( p==0 ) return; |
| 134394 | + if( p->a==0 ) return; |
| 134395 | + if( p->nUsed ){ |
| 134396 | + if( p->bSorted==0 ){ |
| 134397 | + assert( p->nUsed>1 ); |
| 134398 | + percentSort(p->a, p->nUsed); |
| 134399 | + p->bSorted = 1; |
| 134400 | + } |
| 134401 | + ix = p->rPct*(p->nUsed-1); |
| 134402 | + i1 = (unsigned)ix; |
| 134403 | + if( settings & 1 ){ |
| 134404 | + vx = p->a[i1]; |
| 134405 | + }else{ |
| 134406 | + i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; |
| 134407 | + v1 = p->a[i1]; |
| 134408 | + v2 = p->a[i2]; |
| 134409 | + vx = v1 + (v2-v1)*(ix-i1); |
| 134410 | + } |
| 134411 | + sqlite3_result_double(pCtx, vx); |
| 134412 | + } |
| 134413 | + if( bIsFinal ){ |
| 134414 | + sqlite3_free(p->a); |
| 134415 | + memset(p, 0, sizeof(*p)); |
| 134416 | + }else{ |
| 134417 | + p->bKeepSorted = 1; |
| 134418 | + } |
| 134419 | +} |
| 134420 | +static void percentFinal(sqlite3_context *pCtx){ |
| 134421 | + percentCompute(pCtx, 1); |
| 134422 | +} |
| 134423 | +static void percentValue(sqlite3_context *pCtx){ |
| 134424 | + percentCompute(pCtx, 0); |
| 134425 | +} |
| 134426 | +/****** End of percentile family of functions ******/ |
| 134427 | +#endif /* SQLITE_ENABLE_PERCENTILE */ |
| 134428 | + |
| 133864 | 134429 | |
| 133865 | 134430 | #ifdef SQLITE_DEBUG |
| 133866 | 134431 | /* |
| 133867 | 134432 | ** Implementation of fpdecode(x,y,z) function. |
| 133868 | 134433 | ** |
| | @@ -134090,10 +134655,25 @@ |
| 134090 | 134655 | WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, |
| 134091 | 134656 | groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), |
| 134092 | 134657 | WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep, |
| 134093 | 134658 | groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), |
| 134094 | 134659 | |
| 134660 | +#ifdef SQLITE_ENABLE_PERCENTILE |
| 134661 | + WAGGREGATE(median, 1, 0,0, percentStep, |
| 134662 | + percentFinal, percentValue, percentInverse, |
| 134663 | + SQLITE_INNOCUOUS|SQLITE_SELFORDER1), |
| 134664 | + WAGGREGATE(percentile, 2, 0x2,0, percentStep, |
| 134665 | + percentFinal, percentValue, percentInverse, |
| 134666 | + SQLITE_INNOCUOUS|SQLITE_SELFORDER1), |
| 134667 | + WAGGREGATE(percentile_cont, 2, 0,0, percentStep, |
| 134668 | + percentFinal, percentValue, percentInverse, |
| 134669 | + SQLITE_INNOCUOUS|SQLITE_SELFORDER1), |
| 134670 | + WAGGREGATE(percentile_disc, 2, 0x1,0, percentStep, |
| 134671 | + percentFinal, percentValue, percentInverse, |
| 134672 | + SQLITE_INNOCUOUS|SQLITE_SELFORDER1), |
| 134673 | +#endif /* SQLITE_ENABLE_PERCENTILE */ |
| 134674 | + |
| 134095 | 134675 | LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), |
| 134096 | 134676 | #ifdef SQLITE_CASE_SENSITIVE_LIKE |
| 134097 | 134677 | LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), |
| 134098 | 134678 | LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), |
| 134099 | 134679 | #else |
| | @@ -229314,10 +229894,539 @@ |
| 229314 | 229894 | #elif defined(SQLITE_ENABLE_DBPAGE_VTAB) |
| 229315 | 229895 | SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; } |
| 229316 | 229896 | #endif /* SQLITE_ENABLE_DBSTAT_VTAB */ |
| 229317 | 229897 | |
| 229318 | 229898 | /************** End of dbpage.c **********************************************/ |
| 229899 | +/************** Begin file carray.c ******************************************/ |
| 229900 | +/* |
| 229901 | +** 2016-06-29 |
| 229902 | +** |
| 229903 | +** The author disclaims copyright to this source code. In place of |
| 229904 | +** a legal notice, here is a blessing: |
| 229905 | +** |
| 229906 | +** May you do good and not evil. |
| 229907 | +** May you find forgiveness for yourself and forgive others. |
| 229908 | +** May you share freely, never taking more than you give. |
| 229909 | +** |
| 229910 | +************************************************************************* |
| 229911 | +** |
| 229912 | +** This file implements a table-valued-function that |
| 229913 | +** returns the values in a C-language array. |
| 229914 | +** Examples: |
| 229915 | +** |
| 229916 | +** SELECT * FROM carray($ptr,5) |
| 229917 | +** |
| 229918 | +** The query above returns 5 integers contained in a C-language array |
| 229919 | +** at the address $ptr. $ptr is a pointer to the array of integers. |
| 229920 | +** The pointer value must be assigned to $ptr using the |
| 229921 | +** sqlite3_bind_pointer() interface with a pointer type of "carray". |
| 229922 | +** For example: |
| 229923 | +** |
| 229924 | +** static int aX[] = { 53, 9, 17, 2231, 4, 99 }; |
| 229925 | +** int i = sqlite3_bind_parameter_index(pStmt, "$ptr"); |
| 229926 | +** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0); |
| 229927 | +** |
| 229928 | +** There is an optional third parameter to determine the datatype of |
| 229929 | +** the C-language array. Allowed values of the third parameter are |
| 229930 | +** 'int32', 'int64', 'double', 'char*', 'struct iovec'. Example: |
| 229931 | +** |
| 229932 | +** SELECT * FROM carray($ptr,10,'char*'); |
| 229933 | +** |
| 229934 | +** The default value of the third parameter is 'int32'. |
| 229935 | +** |
| 229936 | +** HOW IT WORKS |
| 229937 | +** |
| 229938 | +** The carray "function" is really a virtual table with the |
| 229939 | +** following schema: |
| 229940 | +** |
| 229941 | +** CREATE TABLE carray( |
| 229942 | +** value, |
| 229943 | +** pointer HIDDEN, |
| 229944 | +** count HIDDEN, |
| 229945 | +** ctype TEXT HIDDEN |
| 229946 | +** ); |
| 229947 | +** |
| 229948 | +** If the hidden columns "pointer" and "count" are unconstrained, then |
| 229949 | +** the virtual table has no rows. Otherwise, the virtual table interprets |
| 229950 | +** the integer value of "pointer" as a pointer to the array and "count" |
| 229951 | +** as the number of elements in the array. The virtual table steps through |
| 229952 | +** the array, element by element. |
| 229953 | +*/ |
| 229954 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) |
| 229955 | +/* #include "sqliteInt.h" */ |
| 229956 | +#if defined(_WIN32) || defined(__RTP__) || defined(_WRS_KERNEL) |
| 229957 | + struct iovec { |
| 229958 | + void *iov_base; |
| 229959 | + size_t iov_len; |
| 229960 | + }; |
| 229961 | +#else |
| 229962 | +# include <sys/uio.h> |
| 229963 | +#endif |
| 229964 | + |
| 229965 | +/* |
| 229966 | +** Names of allowed datatypes |
| 229967 | +*/ |
| 229968 | +static const char *azType[] = { "int32", "int64", "double", "char*", |
| 229969 | + "struct iovec" }; |
| 229970 | + |
| 229971 | +/* |
| 229972 | +** Structure used to hold the sqlite3_carray_bind() information |
| 229973 | +*/ |
| 229974 | +typedef struct carray_bind carray_bind; |
| 229975 | +struct carray_bind { |
| 229976 | + void *aData; /* The data */ |
| 229977 | + int nData; /* Number of elements */ |
| 229978 | + int mFlags; /* Control flags */ |
| 229979 | + void (*xDel)(void*); /* Destructor for aData */ |
| 229980 | +}; |
| 229981 | + |
| 229982 | + |
| 229983 | +/* carray_cursor is a subclass of sqlite3_vtab_cursor which will |
| 229984 | +** serve as the underlying representation of a cursor that scans |
| 229985 | +** over rows of the result |
| 229986 | +*/ |
| 229987 | +typedef struct carray_cursor carray_cursor; |
| 229988 | +struct carray_cursor { |
| 229989 | + sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 229990 | + sqlite3_int64 iRowid; /* The rowid */ |
| 229991 | + void *pPtr; /* Pointer to the array of values */ |
| 229992 | + sqlite3_int64 iCnt; /* Number of integers in the array */ |
| 229993 | + unsigned char eType; /* One of the CARRAY_type values */ |
| 229994 | +}; |
| 229995 | + |
| 229996 | +/* |
| 229997 | +** The carrayConnect() method is invoked to create a new |
| 229998 | +** carray_vtab that describes the carray virtual table. |
| 229999 | +** |
| 230000 | +** Think of this routine as the constructor for carray_vtab objects. |
| 230001 | +** |
| 230002 | +** All this routine needs to do is: |
| 230003 | +** |
| 230004 | +** (1) Allocate the carray_vtab object and initialize all fields. |
| 230005 | +** |
| 230006 | +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the |
| 230007 | +** result set of queries against carray will look like. |
| 230008 | +*/ |
| 230009 | +static int carrayConnect( |
| 230010 | + sqlite3 *db, |
| 230011 | + void *pAux, |
| 230012 | + int argc, const char *const*argv, |
| 230013 | + sqlite3_vtab **ppVtab, |
| 230014 | + char **pzErr |
| 230015 | +){ |
| 230016 | + sqlite3_vtab *pNew; |
| 230017 | + int rc; |
| 230018 | + |
| 230019 | +/* Column numbers */ |
| 230020 | +#define CARRAY_COLUMN_VALUE 0 |
| 230021 | +#define CARRAY_COLUMN_POINTER 1 |
| 230022 | +#define CARRAY_COLUMN_COUNT 2 |
| 230023 | +#define CARRAY_COLUMN_CTYPE 3 |
| 230024 | + |
| 230025 | + rc = sqlite3_declare_vtab(db, |
| 230026 | + "CREATE TABLE x(value,pointer hidden,count hidden,ctype hidden)"); |
| 230027 | + if( rc==SQLITE_OK ){ |
| 230028 | + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); |
| 230029 | + if( pNew==0 ) return SQLITE_NOMEM; |
| 230030 | + memset(pNew, 0, sizeof(*pNew)); |
| 230031 | + } |
| 230032 | + return rc; |
| 230033 | +} |
| 230034 | + |
| 230035 | +/* |
| 230036 | +** This method is the destructor for carray_cursor objects. |
| 230037 | +*/ |
| 230038 | +static int carrayDisconnect(sqlite3_vtab *pVtab){ |
| 230039 | + sqlite3_free(pVtab); |
| 230040 | + return SQLITE_OK; |
| 230041 | +} |
| 230042 | + |
| 230043 | +/* |
| 230044 | +** Constructor for a new carray_cursor object. |
| 230045 | +*/ |
| 230046 | +static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 230047 | + carray_cursor *pCur; |
| 230048 | + pCur = sqlite3_malloc( sizeof(*pCur) ); |
| 230049 | + if( pCur==0 ) return SQLITE_NOMEM; |
| 230050 | + memset(pCur, 0, sizeof(*pCur)); |
| 230051 | + *ppCursor = &pCur->base; |
| 230052 | + return SQLITE_OK; |
| 230053 | +} |
| 230054 | + |
| 230055 | +/* |
| 230056 | +** Destructor for a carray_cursor. |
| 230057 | +*/ |
| 230058 | +static int carrayClose(sqlite3_vtab_cursor *cur){ |
| 230059 | + sqlite3_free(cur); |
| 230060 | + return SQLITE_OK; |
| 230061 | +} |
| 230062 | + |
| 230063 | + |
| 230064 | +/* |
| 230065 | +** Advance a carray_cursor to its next row of output. |
| 230066 | +*/ |
| 230067 | +static int carrayNext(sqlite3_vtab_cursor *cur){ |
| 230068 | + carray_cursor *pCur = (carray_cursor*)cur; |
| 230069 | + pCur->iRowid++; |
| 230070 | + return SQLITE_OK; |
| 230071 | +} |
| 230072 | + |
| 230073 | +/* |
| 230074 | +** Return values of columns for the row at which the carray_cursor |
| 230075 | +** is currently pointing. |
| 230076 | +*/ |
| 230077 | +static int carrayColumn( |
| 230078 | + sqlite3_vtab_cursor *cur, /* The cursor */ |
| 230079 | + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
| 230080 | + int i /* Which column to return */ |
| 230081 | +){ |
| 230082 | + carray_cursor *pCur = (carray_cursor*)cur; |
| 230083 | + sqlite3_int64 x = 0; |
| 230084 | + switch( i ){ |
| 230085 | + case CARRAY_COLUMN_POINTER: return SQLITE_OK; |
| 230086 | + case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break; |
| 230087 | + case CARRAY_COLUMN_CTYPE: { |
| 230088 | + sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC); |
| 230089 | + return SQLITE_OK; |
| 230090 | + } |
| 230091 | + default: { |
| 230092 | + switch( pCur->eType ){ |
| 230093 | + case CARRAY_INT32: { |
| 230094 | + int *p = (int*)pCur->pPtr; |
| 230095 | + sqlite3_result_int(ctx, p[pCur->iRowid-1]); |
| 230096 | + return SQLITE_OK; |
| 230097 | + } |
| 230098 | + case CARRAY_INT64: { |
| 230099 | + sqlite3_int64 *p = (sqlite3_int64*)pCur->pPtr; |
| 230100 | + sqlite3_result_int64(ctx, p[pCur->iRowid-1]); |
| 230101 | + return SQLITE_OK; |
| 230102 | + } |
| 230103 | + case CARRAY_DOUBLE: { |
| 230104 | + double *p = (double*)pCur->pPtr; |
| 230105 | + sqlite3_result_double(ctx, p[pCur->iRowid-1]); |
| 230106 | + return SQLITE_OK; |
| 230107 | + } |
| 230108 | + case CARRAY_TEXT: { |
| 230109 | + const char **p = (const char**)pCur->pPtr; |
| 230110 | + sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT); |
| 230111 | + return SQLITE_OK; |
| 230112 | + } |
| 230113 | + default: { |
| 230114 | + const struct iovec *p = (struct iovec*)pCur->pPtr; |
| 230115 | + assert( pCur->eType==CARRAY_BLOB ); |
| 230116 | + sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base, |
| 230117 | + (int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT); |
| 230118 | + return SQLITE_OK; |
| 230119 | + } |
| 230120 | + } |
| 230121 | + } |
| 230122 | + } |
| 230123 | + sqlite3_result_int64(ctx, x); |
| 230124 | + return SQLITE_OK; |
| 230125 | +} |
| 230126 | + |
| 230127 | +/* |
| 230128 | +** Return the rowid for the current row. In this implementation, the |
| 230129 | +** rowid is the same as the output value. |
| 230130 | +*/ |
| 230131 | +static int carrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 230132 | + carray_cursor *pCur = (carray_cursor*)cur; |
| 230133 | + *pRowid = pCur->iRowid; |
| 230134 | + return SQLITE_OK; |
| 230135 | +} |
| 230136 | + |
| 230137 | +/* |
| 230138 | +** Return TRUE if the cursor has been moved off of the last |
| 230139 | +** row of output. |
| 230140 | +*/ |
| 230141 | +static int carrayEof(sqlite3_vtab_cursor *cur){ |
| 230142 | + carray_cursor *pCur = (carray_cursor*)cur; |
| 230143 | + return pCur->iRowid>pCur->iCnt; |
| 230144 | +} |
| 230145 | + |
| 230146 | +/* |
| 230147 | +** This method is called to "rewind" the carray_cursor object back |
| 230148 | +** to the first row of output. |
| 230149 | +*/ |
| 230150 | +static int carrayFilter( |
| 230151 | + sqlite3_vtab_cursor *pVtabCursor, |
| 230152 | + int idxNum, const char *idxStr, |
| 230153 | + int argc, sqlite3_value **argv |
| 230154 | +){ |
| 230155 | + carray_cursor *pCur = (carray_cursor *)pVtabCursor; |
| 230156 | + pCur->pPtr = 0; |
| 230157 | + pCur->iCnt = 0; |
| 230158 | + switch( idxNum ){ |
| 230159 | + case 1: { |
| 230160 | + carray_bind *pBind = sqlite3_value_pointer(argv[0], "carray-bind"); |
| 230161 | + if( pBind==0 ) break; |
| 230162 | + pCur->pPtr = pBind->aData; |
| 230163 | + pCur->iCnt = pBind->nData; |
| 230164 | + pCur->eType = pBind->mFlags & 0x07; |
| 230165 | + break; |
| 230166 | + } |
| 230167 | + case 2: |
| 230168 | + case 3: { |
| 230169 | + pCur->pPtr = sqlite3_value_pointer(argv[0], "carray"); |
| 230170 | + pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0; |
| 230171 | + if( idxNum<3 ){ |
| 230172 | + pCur->eType = CARRAY_INT32; |
| 230173 | + }else{ |
| 230174 | + unsigned char i; |
| 230175 | + const char *zType = (const char*)sqlite3_value_text(argv[2]); |
| 230176 | + for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){ |
| 230177 | + if( sqlite3_stricmp(zType, azType[i])==0 ) break; |
| 230178 | + } |
| 230179 | + if( i>=sizeof(azType)/sizeof(azType[0]) ){ |
| 230180 | + pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf( |
| 230181 | + "unknown datatype: %Q", zType); |
| 230182 | + return SQLITE_ERROR; |
| 230183 | + }else{ |
| 230184 | + pCur->eType = i; |
| 230185 | + } |
| 230186 | + } |
| 230187 | + break; |
| 230188 | + } |
| 230189 | + } |
| 230190 | + pCur->iRowid = 1; |
| 230191 | + return SQLITE_OK; |
| 230192 | +} |
| 230193 | + |
| 230194 | +/* |
| 230195 | +** SQLite will invoke this method one or more times while planning a query |
| 230196 | +** that uses the carray virtual table. This routine needs to create |
| 230197 | +** a query plan for each invocation and compute an estimated cost for that |
| 230198 | +** plan. |
| 230199 | +** |
| 230200 | +** In this implementation idxNum is used to represent the |
| 230201 | +** query plan. idxStr is unused. |
| 230202 | +** |
| 230203 | +** idxNum is: |
| 230204 | +** |
| 230205 | +** 1 If only the pointer= constraint exists. In this case, the |
| 230206 | +** parameter must be bound using sqlite3_carray_bind(). |
| 230207 | +** |
| 230208 | +** 2 if the pointer= and count= constraints exist. |
| 230209 | +** |
| 230210 | +** 3 if the ctype= constraint also exists. |
| 230211 | +** |
| 230212 | +** idxNum is 0 otherwise and carray becomes an empty table. |
| 230213 | +*/ |
| 230214 | +static int carrayBestIndex( |
| 230215 | + sqlite3_vtab *tab, |
| 230216 | + sqlite3_index_info *pIdxInfo |
| 230217 | +){ |
| 230218 | + int i; /* Loop over constraints */ |
| 230219 | + int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */ |
| 230220 | + int cntIdx = -1; /* Index of the count= constraint, or -1 if none */ |
| 230221 | + int ctypeIdx = -1; /* Index of the ctype= constraint, or -1 if none */ |
| 230222 | + unsigned seen = 0; /* Bitmask of == constrainted columns */ |
| 230223 | + |
| 230224 | + const struct sqlite3_index_constraint *pConstraint; |
| 230225 | + pConstraint = pIdxInfo->aConstraint; |
| 230226 | + for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 230227 | + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
| 230228 | + if( pConstraint->iColumn>=0 ) seen |= 1 << pConstraint->iColumn; |
| 230229 | + if( pConstraint->usable==0 ) continue; |
| 230230 | + switch( pConstraint->iColumn ){ |
| 230231 | + case CARRAY_COLUMN_POINTER: |
| 230232 | + ptrIdx = i; |
| 230233 | + break; |
| 230234 | + case CARRAY_COLUMN_COUNT: |
| 230235 | + cntIdx = i; |
| 230236 | + break; |
| 230237 | + case CARRAY_COLUMN_CTYPE: |
| 230238 | + ctypeIdx = i; |
| 230239 | + break; |
| 230240 | + } |
| 230241 | + } |
| 230242 | + if( ptrIdx>=0 ){ |
| 230243 | + pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1; |
| 230244 | + pIdxInfo->aConstraintUsage[ptrIdx].omit = 1; |
| 230245 | + pIdxInfo->estimatedCost = (double)1; |
| 230246 | + pIdxInfo->estimatedRows = 100; |
| 230247 | + pIdxInfo->idxNum = 1; |
| 230248 | + if( cntIdx>=0 ){ |
| 230249 | + pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2; |
| 230250 | + pIdxInfo->aConstraintUsage[cntIdx].omit = 1; |
| 230251 | + pIdxInfo->idxNum = 2; |
| 230252 | + if( ctypeIdx>=0 ){ |
| 230253 | + pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3; |
| 230254 | + pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1; |
| 230255 | + pIdxInfo->idxNum = 3; |
| 230256 | + }else if( seen & (1<<CARRAY_COLUMN_CTYPE) ){ |
| 230257 | + /* In a three-argument carray(), we need to know the value of all |
| 230258 | + ** three arguments */ |
| 230259 | + return SQLITE_CONSTRAINT; |
| 230260 | + } |
| 230261 | + }else if( seen & (1<<CARRAY_COLUMN_COUNT) ){ |
| 230262 | + /* In a two-argument carray(), we need to know the value of both |
| 230263 | + ** arguments */ |
| 230264 | + return SQLITE_CONSTRAINT; |
| 230265 | + } |
| 230266 | + }else{ |
| 230267 | + pIdxInfo->estimatedCost = (double)2147483647; |
| 230268 | + pIdxInfo->estimatedRows = 2147483647; |
| 230269 | + pIdxInfo->idxNum = 0; |
| 230270 | + } |
| 230271 | + return SQLITE_OK; |
| 230272 | +} |
| 230273 | + |
| 230274 | +/* |
| 230275 | +** This following structure defines all the methods for the |
| 230276 | +** carray virtual table. |
| 230277 | +*/ |
| 230278 | +static sqlite3_module carrayModule = { |
| 230279 | + 0, /* iVersion */ |
| 230280 | + 0, /* xCreate */ |
| 230281 | + carrayConnect, /* xConnect */ |
| 230282 | + carrayBestIndex, /* xBestIndex */ |
| 230283 | + carrayDisconnect, /* xDisconnect */ |
| 230284 | + 0, /* xDestroy */ |
| 230285 | + carrayOpen, /* xOpen - open a cursor */ |
| 230286 | + carrayClose, /* xClose - close a cursor */ |
| 230287 | + carrayFilter, /* xFilter - configure scan constraints */ |
| 230288 | + carrayNext, /* xNext - advance a cursor */ |
| 230289 | + carrayEof, /* xEof - check for end of scan */ |
| 230290 | + carrayColumn, /* xColumn - read data */ |
| 230291 | + carrayRowid, /* xRowid - read data */ |
| 230292 | + 0, /* xUpdate */ |
| 230293 | + 0, /* xBegin */ |
| 230294 | + 0, /* xSync */ |
| 230295 | + 0, /* xCommit */ |
| 230296 | + 0, /* xRollback */ |
| 230297 | + 0, /* xFindMethod */ |
| 230298 | + 0, /* xRename */ |
| 230299 | + 0, /* xSavepoint */ |
| 230300 | + 0, /* xRelease */ |
| 230301 | + 0, /* xRollbackTo */ |
| 230302 | + 0, /* xShadow */ |
| 230303 | + 0 /* xIntegrity */ |
| 230304 | +}; |
| 230305 | + |
| 230306 | +/* |
| 230307 | +** Destructor for the carray_bind object |
| 230308 | +*/ |
| 230309 | +static void carrayBindDel(void *pPtr){ |
| 230310 | + carray_bind *p = (carray_bind*)pPtr; |
| 230311 | + if( p->xDel!=SQLITE_STATIC ){ |
| 230312 | + p->xDel(p->aData); |
| 230313 | + } |
| 230314 | + sqlite3_free(p); |
| 230315 | +} |
| 230316 | + |
| 230317 | +/* |
| 230318 | +** Invoke this interface in order to bind to the single-argument |
| 230319 | +** version of CARRAY(). |
| 230320 | +*/ |
| 230321 | +SQLITE_API int sqlite3_carray_bind( |
| 230322 | + sqlite3_stmt *pStmt, |
| 230323 | + int idx, |
| 230324 | + void *aData, |
| 230325 | + int nData, |
| 230326 | + int mFlags, |
| 230327 | + void (*xDestroy)(void*) |
| 230328 | +){ |
| 230329 | + carray_bind *pNew = 0; |
| 230330 | + int i; |
| 230331 | + int rc = SQLITE_OK; |
| 230332 | + |
| 230333 | + /* Ensure that the mFlags value is acceptable. */ |
| 230334 | + assert( CARRAY_INT32==0 && CARRAY_INT64==1 && CARRAY_DOUBLE==2 ); |
| 230335 | + assert( CARRAY_TEXT==3 && CARRAY_BLOB==4 ); |
| 230336 | + if( mFlags<CARRAY_INT32 || mFlags>CARRAY_BLOB ){ |
| 230337 | + rc = SQLITE_ERROR; |
| 230338 | + goto carray_bind_error; |
| 230339 | + } |
| 230340 | + |
| 230341 | + pNew = sqlite3_malloc64(sizeof(*pNew)); |
| 230342 | + if( pNew==0 ){ |
| 230343 | + rc = SQLITE_NOMEM; |
| 230344 | + goto carray_bind_error; |
| 230345 | + } |
| 230346 | + |
| 230347 | + pNew->nData = nData; |
| 230348 | + pNew->mFlags = mFlags; |
| 230349 | + if( xDestroy==SQLITE_TRANSIENT ){ |
| 230350 | + sqlite3_int64 sz = nData; |
| 230351 | + switch( mFlags ){ |
| 230352 | + case CARRAY_INT32: sz *= 4; break; |
| 230353 | + case CARRAY_INT64: sz *= 8; break; |
| 230354 | + case CARRAY_DOUBLE: sz *= 8; break; |
| 230355 | + case CARRAY_TEXT: sz *= sizeof(char*); break; |
| 230356 | + default: sz *= sizeof(struct iovec); break; |
| 230357 | + } |
| 230358 | + if( mFlags==CARRAY_TEXT ){ |
| 230359 | + for(i=0; i<nData; i++){ |
| 230360 | + const char *z = ((char**)aData)[i]; |
| 230361 | + if( z ) sz += strlen(z) + 1; |
| 230362 | + } |
| 230363 | + }else if( mFlags==CARRAY_BLOB ){ |
| 230364 | + for(i=0; i<nData; i++){ |
| 230365 | + sz += ((struct iovec*)aData)[i].iov_len; |
| 230366 | + } |
| 230367 | + } |
| 230368 | + |
| 230369 | + pNew->aData = sqlite3_malloc64( sz ); |
| 230370 | + if( pNew->aData==0 ){ |
| 230371 | + rc = SQLITE_NOMEM; |
| 230372 | + goto carray_bind_error; |
| 230373 | + } |
| 230374 | + |
| 230375 | + if( mFlags==CARRAY_TEXT ){ |
| 230376 | + char **az = (char**)pNew->aData; |
| 230377 | + char *z = (char*)&az[nData]; |
| 230378 | + for(i=0; i<nData; i++){ |
| 230379 | + const char *zData = ((char**)aData)[i]; |
| 230380 | + sqlite3_int64 n; |
| 230381 | + if( zData==0 ){ |
| 230382 | + az[i] = 0; |
| 230383 | + continue; |
| 230384 | + } |
| 230385 | + az[i] = z; |
| 230386 | + n = strlen(zData); |
| 230387 | + memcpy(z, zData, n+1); |
| 230388 | + z += n+1; |
| 230389 | + } |
| 230390 | + }else if( mFlags==CARRAY_BLOB ){ |
| 230391 | + struct iovec *p = (struct iovec*)pNew->aData; |
| 230392 | + unsigned char *z = (unsigned char*)&p[nData]; |
| 230393 | + for(i=0; i<nData; i++){ |
| 230394 | + size_t n = ((struct iovec*)aData)[i].iov_len; |
| 230395 | + p[i].iov_len = n; |
| 230396 | + p[i].iov_base = z; |
| 230397 | + z += n; |
| 230398 | + memcpy(p[i].iov_base, ((struct iovec*)aData)[i].iov_base, n); |
| 230399 | + } |
| 230400 | + }else{ |
| 230401 | + memcpy(pNew->aData, aData, sz); |
| 230402 | + } |
| 230403 | + pNew->xDel = sqlite3_free; |
| 230404 | + }else{ |
| 230405 | + pNew->aData = aData; |
| 230406 | + pNew->xDel = xDestroy; |
| 230407 | + } |
| 230408 | + return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel); |
| 230409 | + |
| 230410 | + carray_bind_error: |
| 230411 | + if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){ |
| 230412 | + xDestroy(aData); |
| 230413 | + } |
| 230414 | + sqlite3_free(pNew); |
| 230415 | + return rc; |
| 230416 | +} |
| 230417 | + |
| 230418 | +/* |
| 230419 | +** Invoke this routine to register the carray() function. |
| 230420 | +*/ |
| 230421 | +SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3 *db){ |
| 230422 | + return sqlite3VtabCreateModule(db, "carray", &carrayModule, 0, 0); |
| 230423 | +} |
| 230424 | + |
| 230425 | +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) */ |
| 230426 | + |
| 230427 | +/************** End of carray.c **********************************************/ |
| 229319 | 230428 | /************** Begin file sqlite3session.c **********************************/ |
| 229320 | 230429 | |
| 229321 | 230430 | #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) |
| 229322 | 230431 | /* #include "sqlite3session.h" */ |
| 229323 | 230432 | /* #include <assert.h> */ |
| | @@ -258724,11 +259833,11 @@ |
| 258724 | 259833 | int nArg, /* Number of args */ |
| 258725 | 259834 | sqlite3_value **apUnused /* Function arguments */ |
| 258726 | 259835 | ){ |
| 258727 | 259836 | assert( nArg==0 ); |
| 258728 | 259837 | UNUSED_PARAM2(nArg, apUnused); |
| 258729 | | - sqlite3_result_text(pCtx, "fts5: 2025-10-02 11:28:27 22b2700ac20bb8e5883d484bfd0aee7a0fbc99b92696d8ca850cd129e2ccbb43", -1, SQLITE_TRANSIENT); |
| 259838 | + sqlite3_result_text(pCtx, "fts5: 2025-10-10 14:22:05 fe9cf68b513d1e8cfcde90f1982a7f4123f54e3ebb004d961a99bdf6bec03a32", -1, SQLITE_TRANSIENT); |
| 258730 | 259839 | } |
| 258731 | 259840 | |
| 258732 | 259841 | /* |
| 258733 | 259842 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 258734 | 259843 | ** |
| | @@ -259041,20 +260150,20 @@ |
| 259041 | 260150 | ** must be read from the saved row stored in Fts5Storage.pSavedRow. |
| 259042 | 260151 | ** |
| 259043 | 260152 | ** This is necessary - using sqlite3_value_nochange() instead of just having |
| 259044 | 260153 | ** SQLite pass the original value back via xUpdate() - so as not to discard |
| 259045 | 260154 | ** any locale information associated with such values. |
| 259046 | | -** |
| 259047 | 260155 | */ |
| 259048 | 260156 | struct Fts5Storage { |
| 259049 | 260157 | Fts5Config *pConfig; |
| 259050 | 260158 | Fts5Index *pIndex; |
| 260159 | + int db_enc; /* Database encoding */ |
| 259051 | 260160 | int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ |
| 259052 | 260161 | i64 nTotalRow; /* Total number of rows in FTS table */ |
| 259053 | 260162 | i64 *aTotalSize; /* Total sizes of each column */ |
| 259054 | 260163 | sqlite3_stmt *pSavedRow; |
| 259055 | | - sqlite3_stmt *aStmt[12]; |
| 260164 | + sqlite3_stmt *aStmt[13]; |
| 259056 | 260165 | }; |
| 259057 | 260166 | |
| 259058 | 260167 | |
| 259059 | 260168 | #if FTS5_STMT_SCAN_ASC!=0 |
| 259060 | 260169 | # error "FTS5_STMT_SCAN_ASC mismatch" |
| | @@ -259073,10 +260182,11 @@ |
| 259073 | 260182 | #define FTS5_STMT_REPLACE_DOCSIZE 7 |
| 259074 | 260183 | #define FTS5_STMT_DELETE_DOCSIZE 8 |
| 259075 | 260184 | #define FTS5_STMT_LOOKUP_DOCSIZE 9 |
| 259076 | 260185 | #define FTS5_STMT_REPLACE_CONFIG 10 |
| 259077 | 260186 | #define FTS5_STMT_SCAN 11 |
| 260187 | +#define FTS5_STMT_ENC_CONVERT 12 |
| 259078 | 260188 | |
| 259079 | 260189 | /* |
| 259080 | 260190 | ** Prepare the two insert statements - Fts5Storage.pInsertContent and |
| 259081 | 260191 | ** Fts5Storage.pInsertDocsize - if they have not already been prepared. |
| 259082 | 260192 | ** Return SQLITE_OK if successful, or an SQLite error code if an error |
| | @@ -259114,10 +260224,11 @@ |
| 259114 | 260224 | |
| 259115 | 260225 | "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ |
| 259116 | 260226 | |
| 259117 | 260227 | "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ |
| 259118 | 260228 | "SELECT %s FROM %s AS T", /* SCAN */ |
| 260229 | + "SELECT substr(?, 1)", /* ENC_CONVERT */ |
| 259119 | 260230 | }; |
| 259120 | 260231 | Fts5Config *pC = p->pConfig; |
| 259121 | 260232 | char *zSql = 0; |
| 259122 | 260233 | |
| 259123 | 260234 | assert( ArraySize(azStmt)==ArraySize(p->aStmt) ); |
| | @@ -259333,10 +260444,40 @@ |
| 259333 | 260444 | sqlite3_free(zErr); |
| 259334 | 260445 | } |
| 259335 | 260446 | |
| 259336 | 260447 | return rc; |
| 259337 | 260448 | } |
| 260449 | + |
| 260450 | +/* |
| 260451 | +** Set the value of Fts5Storage.db_enc to the db encoding. Return SQLITE_OK |
| 260452 | +** if successful, or an SQLite error code otherwise. |
| 260453 | +*/ |
| 260454 | +static int fts5StorageFindDbEnc(Fts5Storage *p){ |
| 260455 | + const char *zSql = "PRAGMA encoding"; |
| 260456 | + sqlite3_stmt *pStmt = 0; |
| 260457 | + int rc = SQLITE_OK; |
| 260458 | + |
| 260459 | + rc = sqlite3_prepare(p->pConfig->db, zSql, -1, &pStmt, 0); |
| 260460 | + if( rc==SQLITE_OK ){ |
| 260461 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 260462 | + static const char *aEnc[] = { |
| 260463 | + "UTF-8", "UTF-16le", "UTF-16be" |
| 260464 | + }; |
| 260465 | + const char *zEnc = (const char*)sqlite3_column_text(pStmt, 0); |
| 260466 | + int ii; |
| 260467 | + for(ii=0; ii<ArraySize(aEnc); ii++){ |
| 260468 | + if( sqlite3_stricmp(aEnc[ii], zEnc)==0 ){ |
| 260469 | + p->db_enc = ii+1; |
| 260470 | + break; |
| 260471 | + } |
| 260472 | + } |
| 260473 | + } |
| 260474 | + rc = sqlite3_finalize(pStmt); |
| 260475 | + } |
| 260476 | + |
| 260477 | + return rc; |
| 260478 | +} |
| 259338 | 260479 | |
| 259339 | 260480 | /* |
| 259340 | 260481 | ** Open a new Fts5Index handle. If the bCreate argument is true, create |
| 259341 | 260482 | ** and initialize the underlying tables |
| 259342 | 260483 | ** |
| | @@ -259362,11 +260503,13 @@ |
| 259362 | 260503 | memset(p, 0, (size_t)nByte); |
| 259363 | 260504 | p->aTotalSize = (i64*)&p[1]; |
| 259364 | 260505 | p->pConfig = pConfig; |
| 259365 | 260506 | p->pIndex = pIndex; |
| 259366 | 260507 | |
| 259367 | | - if( bCreate ){ |
| 260508 | + rc = fts5StorageFindDbEnc(p); |
| 260509 | + |
| 260510 | + if( rc==SQLITE_OK && bCreate ){ |
| 259368 | 260511 | if( pConfig->eContent==FTS5_CONTENT_NORMAL |
| 259369 | 260512 | || pConfig->eContent==FTS5_CONTENT_UNINDEXED |
| 259370 | 260513 | ){ |
| 259371 | 260514 | int nDefn = 32 + pConfig->nCol*10; |
| 259372 | 260515 | char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); |
| | @@ -260031,10 +261174,63 @@ |
| 260031 | 261174 | *piRowid = sqlite3_last_insert_rowid(pConfig->db); |
| 260032 | 261175 | } |
| 260033 | 261176 | |
| 260034 | 261177 | return rc; |
| 260035 | 261178 | } |
| 261179 | + |
| 261180 | +/* |
| 261181 | +** Argument pVal is a blob value for which the internal encoding does not |
| 261182 | +** match the database encoding. This happens when using sqlite3_bind_blob() |
| 261183 | +** (which always sets encoding=utf8) with a utf-16 database. The problem |
| 261184 | +** is that fts5 is about to call sqlite3_column_text() on the value to |
| 261185 | +** obtain text for tokenization. And the conversion between text and blob |
| 261186 | +** must take place assuming the blob is encoded in database encoding - |
| 261187 | +** otherwise it won't match the text extracted from the same blob if it |
| 261188 | +** is read from the db later on. |
| 261189 | +** |
| 261190 | +** This function attempts to create a new value containing a copy of |
| 261191 | +** the blob in pVal, but with the encoding set to the database encoding. |
| 261192 | +** If successful, it sets (*ppOut) to point to the new value and returns |
| 261193 | +** SQLITE_OK. It is the responsibility of the caller to eventually free |
| 261194 | +** this value using sqlite3_value_free(). Or, if an error occurs, (*ppOut) |
| 261195 | +** is set to NULL and an SQLite error code returned. |
| 261196 | +*/ |
| 261197 | +static int fts5EncodingFix( |
| 261198 | + Fts5Storage *p, |
| 261199 | + sqlite3_value *pVal, |
| 261200 | + sqlite3_value **ppOut |
| 261201 | +){ |
| 261202 | + sqlite3_stmt *pStmt = 0; |
| 261203 | + int rc = fts5StorageGetStmt( |
| 261204 | + p, FTS5_STMT_ENC_CONVERT, &pStmt, p->pConfig->pzErrmsg |
| 261205 | + ); |
| 261206 | + if( rc==SQLITE_OK ){ |
| 261207 | + sqlite3_value *pDup = 0; |
| 261208 | + const char *pBlob = sqlite3_value_blob(pVal); |
| 261209 | + int nBlob = sqlite3_value_bytes(pVal); |
| 261210 | + |
| 261211 | + sqlite3_bind_blob(pStmt, 1, pBlob, nBlob, SQLITE_STATIC); |
| 261212 | + |
| 261213 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 261214 | + sqlite3_value *pX = sqlite3_column_value(pStmt, 0); |
| 261215 | + pDup = sqlite3_value_dup(pX); |
| 261216 | + if( pDup==0 ){ |
| 261217 | + rc = SQLITE_NOMEM; |
| 261218 | + }else{ |
| 261219 | + *ppOut = pX; |
| 261220 | + } |
| 261221 | + } |
| 261222 | + rc = sqlite3_reset(pStmt); |
| 261223 | + if( rc!=SQLITE_OK ){ |
| 261224 | + sqlite3_value_free(pDup); |
| 261225 | + }else{ |
| 261226 | + *ppOut = pDup; |
| 261227 | + } |
| 261228 | + } |
| 261229 | + |
| 261230 | + return rc; |
| 261231 | +} |
| 260036 | 261232 | |
| 260037 | 261233 | /* |
| 260038 | 261234 | ** Insert new entries into the FTS index and %_docsize table. |
| 260039 | 261235 | */ |
| 260040 | 261236 | static int sqlite3Fts5StorageIndexInsert( |
| | @@ -260059,10 +261255,11 @@ |
| 260059 | 261255 | if( pConfig->abUnindexed[ctx.iCol]==0 ){ |
| 260060 | 261256 | int nText = 0; /* Size of pText in bytes */ |
| 260061 | 261257 | const char *pText = 0; /* Pointer to buffer containing text value */ |
| 260062 | 261258 | int nLoc = 0; /* Size of pText in bytes */ |
| 260063 | 261259 | const char *pLoc = 0; /* Pointer to buffer containing text value */ |
| 261260 | + sqlite3_value *pFree = 0; |
| 260064 | 261261 | |
| 260065 | 261262 | sqlite3_value *pVal = apVal[ctx.iCol+2]; |
| 260066 | 261263 | if( p->pSavedRow && sqlite3_value_nochange(pVal) ){ |
| 260067 | 261264 | pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1); |
| 260068 | 261265 | if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ |
| | @@ -260075,10 +261272,19 @@ |
| 260075 | 261272 | } |
| 260076 | 261273 | |
| 260077 | 261274 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 260078 | 261275 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 260079 | 261276 | }else{ |
| 261277 | + if( sqlite3_value_type(pVal)==SQLITE_BLOB |
| 261278 | + && sqlite3_value_encoding(pVal)!=p->db_enc |
| 261279 | + ){ |
| 261280 | + rc = fts5EncodingFix(p, pVal, &pFree); |
| 261281 | + if( pFree ){ |
| 261282 | + assert( rc==SQLITE_OK ); |
| 261283 | + pVal = pFree; |
| 261284 | + } |
| 261285 | + } |
| 260080 | 261286 | pText = (const char*)sqlite3_value_text(pVal); |
| 260081 | 261287 | nText = sqlite3_value_bytes(pVal); |
| 260082 | 261288 | } |
| 260083 | 261289 | |
| 260084 | 261290 | if( rc==SQLITE_OK ){ |
| | @@ -260087,10 +261293,13 @@ |
| 260087 | 261293 | FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, |
| 260088 | 261294 | fts5StorageInsertCallback |
| 260089 | 261295 | ); |
| 260090 | 261296 | sqlite3Fts5ClearLocale(pConfig); |
| 260091 | 261297 | } |
| 261298 | + if( pFree ){ |
| 261299 | + sqlite3_value_free(pFree); |
| 261300 | + } |
| 260092 | 261301 | } |
| 260093 | 261302 | sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); |
| 260094 | 261303 | p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; |
| 260095 | 261304 | } |
| 260096 | 261305 | p->nTotalRow++; |
| 260097 | 261306 | |